日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

HDU2819Swap(二分图最大匹配)

發(fā)布時(shí)間:2025/4/16 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 HDU2819Swap(二分图最大匹配) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

題目鏈接??http://acm.hdu.edu.cn/showproblem.php?pid=2819

??? 題目大意很明確,交換圖的某些行或者是某些列(可以都換),使得這個(gè)N*N的圖對(duì)角線上全部都是1.

??? 這里有一點(diǎn)需要說明,就是說題目的交換,其實(shí)是將原來圖的某一行移到最后圖的某一行,而不是指先交換兩行,得到一個(gè)新圖,再交換新圖的兩行。感覺這里比較坑。

??? 這里先說明的一點(diǎn)就是,如果通過交換某些行沒有辦法的到解的話,那么只交換列 或者 既交換行又交換列 那也沒辦法得到解。其實(shí)個(gè)人感覺這個(gè)可以用矩陣的秩來解釋,所有的對(duì)角線都是1,所以也就是矩陣的秩就是N,所以秩小于N就無(wú)解。另外,根據(jù)矩陣的性質(zhì),任意交換矩陣的兩行? 或者? 兩列,矩陣的秩不變,也就保證了如果通過?只交換行? 或? 只交換列 無(wú)法得到解的話,那么其他交換形式也必然無(wú)解。

??? 既然說是用二分圖的最大匹配,那怎么構(gòu)建二分圖呢,我們構(gòu)建的二分圖,第一部分X表示的是橫坐標(biāo),第二部分Y表示縱坐標(biāo),所以范圍都是1~N,然后如果a[i][j]是1,那我們就從X的i向Y的j引一條邊,那么這條邊的含義就可以解釋為可以將Y的第j列(因?yàn)閅表示的是列的集合)移到第i列,使得a[i][i]變成1,這樣就相當(dāng)于是第i行第i列就變成了1,也就是說對(duì)角線多了一個(gè)1。

??? 因此我們求這個(gè)二分圖的最大匹配目的是為了讓每一列只與X中的某一行匹配),這樣來就形成了N條邊,那我們只需要將所有匹配的邊的右邊(列)? 和? 左邊(行)所在的列? 交換,這樣一來對(duì)角線上這一行就成了1.

??? 上面也也正好提示了如果最大匹配是N,那就存在解,否則無(wú)解。

1 #include <map> 2 #include <set> 3 #include <stack> 4 #include <queue> 5 #include <cmath> 6 #include <ctime> 7 #include <vector> 8 #include <cstdio> 9 #include <cctype> 10 #include <cstring> 11 #include <cstdlib> 12 #include <iostream> 13 #include <algorithm> 14 using namespace std; 15 #define eps 1e-15 16 #define MAXN 105 17 #define INF 1000000007 18 #define MAX(a,b) (a > b ? a : b) 19 #define MIN(a,b) (a < b ? a : b) 20 #define mem(a) memset(a,0,sizeof(a)) 21 22 bool G[MAXN][MAXN],vis[MAXN]; 23 int Left[MAXN],N,M,T,a[MAXN],b[MAXN]; 24 25 bool DFS(int u) 26 { 27 for(int v=0;v<=N;v++) if(G[u][v] && !vis[v]) 28 { 29 vis[v] = true; 30 if(!Left[v] || DFS(Left[v])) 31 { 32 Left[v] = u; 33 return true; 34 } 35 } 36 return false; 37 } 38 39 int main() 40 { 41 while(~scanf("%d", &N)) 42 { 43 mem(G); mem(Left); 44 int x,ans = 0; 45 for(int i=1;i<=N;i++) for(int j=1;j<=N;j++) 46 { 47 scanf("%d", &x); 48 if(x)G[i][j] = true; 49 } 50 for(int i=1;i<=N;i++)//求最大匹配 51 { 52 mem(vis); 53 if(DFS(i)) ans ++; 54 } 55 if(ans < N){printf("-1\n");continue;}//小于N無(wú)解 56 int tot = 0,j; 57 for(int i=1;i<=N;i++) 58 { 59 for(j=1;j<=N && Left[j]!=i ;j++); 60 if(i != j)//交換第i列和第j列 61 { 62 a[tot] = i; b[tot] = j; tot ++;//記錄結(jié)果 63 int t = Left[i]; Left[i] = Left[j]; Left[j] = t; 64 } 65 } 66 printf("%d\n",tot); 67 for(int i=0;i<tot;i++) printf("C %d %d\n", a[i],b[i]); 68 } 69 return 0; 70 }

?

轉(zhuǎn)載于:https://www.cnblogs.com/gj-Acit/p/3265502.html

《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀

總結(jié)

以上是生活随笔為你收集整理的HDU2819Swap(二分图最大匹配)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。