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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

二分图多重匹配

發布時間:2023/12/10 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 二分图多重匹配 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

?

在二分圖的最大匹配中,每個點(不管是X集合還是Y集合)最多只能與一條匹配邊相關聯,

然而,經常有這種問題,即二分圖的一個點可以和多條匹配邊相關聯,但有上限,即cap[i]表示點i最多能和cap[i]條匹配邊相關聯。

?

hdu 3605

題意:2012來了,n個人可以逃往m個星球中的k個,每個星球都有上限,問所有的人能不能都都逃亡成功;

?

?

1 #include <stdio.h> 2 #include <string.h> 3 const int N = 100000 + 10; 4 const int M = 10 + 10; 5 int n,m; 6 int Map[N][M]; 7 int cap[M];//星球i的容量上限 8 int cy[M][N]; 9 int num[M];//num[i]記錄星球i已經匹配了n個人 10 bool vis[M]; 11 12 13 bool dfs(int u) 14 { 15 for(int i=0; i<m; ++i) 16 { 17 if(!vis[i] && Map[u][i]) 18 { 19 vis[i] = true; 20 if(num[i] < cap[i]) 21 { 22 cy[i][num[i]++] = u; 23 return true; 24 } 25 else 26 { 27 for(int j=0; j<cap[i]; ++j)//尋找增廣路,可以從u出發,經過n條匹配邊中的一條找到增廣路就行 28 { 29 if(dfs(cy[i][j])) 30 { 31 cy[i][j] = u; 32 return true; 33 } 34 } 35 } 36 } 37 } 38 return false; 39 } 40 bool MulMatch() 41 { 42 memset(num, 0, sizeof(num)); 43 for(int i=0; i<n; ++i) 44 { 45 memset(vis, 0, sizeof(vis)); 46 if(!dfs(i)) 47 return false; 48 } 49 return true; 50 } 51 int main() 52 { 53 int i,j; 54 while(scanf("%d%d",&n,&m)!=EOF) 55 { 56 for(i=0; i<n; ++i) 57 for(j=0; j<m; ++j) 58 scanf("%d",&Map[i][j]); 59 60 for(i=0; i<m; ++i) 61 scanf("%d",&cap[i]); 62 printf("%s\n",MulMatch()?"YES":"NO"); 63 } 64 65 return 0; 66 }

?hdu 1669

題意:給定n個人,m個組,沒個人適合m個組中的k個,由給定的數據說明,
要求分組后,人最多的那個組是所有可能情況中最小的

組的人數的情況可能是0--->n ?,但是一個一個枚舉太耗時了,所以用二分枚舉最大組的容量上限,剩下的代碼就都和上面那題一樣

1 #include <stdio.h> 2 #include <string.h> 3 #include <vector> 4 using namespace std; 5 const int nMax = 1000 + 10; 6 const int mMax = 555 + 10; 7 int num[mMax]; 8 bool vis[mMax]; 9 int cy[mMax][nMax]; 10 vector<int> G[nMax]; 11 int n,m,limit; 12 13 void init() 14 { 15 for(int i=0; i<n; ++i) 16 G[i].clear(); 17 } 18 bool dfs(int u) 19 { 20 for(int i=0; i<G[u].size(); ++i) 21 { 22 int v = G[u][i]; 23 if(!vis[v]) 24 { 25 vis[v] = true; 26 if(num[v] < limit) 27 { 28 cy[v][num[v]++] = u; 29 return true; 30 } 31 for(int j=0; j<limit; ++j) 32 if(dfs(cy[v][j])) 33 { 34 cy[v][j] = u; 35 return true; 36 } 37 38 } 39 } 40 return false; 41 } 42 bool MulMatch() 43 { 44 memset(num, 0, sizeof(num)); 45 memset(cy, 0, sizeof(cy)); 46 for(int i=0; i<n; ++i) 47 { 48 memset(vis, 0, sizeof(vis)); 49 if(!dfs(i)) 50 return false; 51 } 52 return true; 53 } 54 int main() 55 { 56 char str[20]; 57 int i,j; 58 while(true) 59 { 60 scanf("%d%d",&n,&m); 61 if(n==0 && m==0) 62 break; 63 init(); 64 for(i=0; i<n; ++i) 65 { 66 scanf("%s",str); 67 while( getchar()==' ') 68 { 69 scanf("%d",&j); 70 G[i].push_back(j); 71 } 72 } 73 int low = 0, high = n,ans = 0; 74 while(low <= high) 75 { 76 limit = (low + high) >> 1;//二分枚舉最大組的容量上限為limit 77 if(MulMatch()) 78 { 79 ans = limit; 80 high = limit - 1; 81 } 82 else 83 low = limit + 1; 84 } 85 printf("%d\n",ans); 86 } 87 return 0; 88 }

?

轉載于:https://www.cnblogs.com/justPassBy/p/4025031.html

總結

以上是生活随笔為你收集整理的二分图多重匹配的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。