匈牙利演算法(二分圖匹配問題)
阿新 • • 發佈:2018-12-03
匈牙利演算法(二分圖匹配問題)
問題連結(杭電2063題):http://acm.hdu.edu.cn/showproblem.php?pid=2063
參考部落格:https://blog.csdn.net/cillyb/article/details/55511666
找伴侶是個遞迴的過程,最最關鍵的字就是“騰”字
其原則大概是:有機會上,沒機會創造機會也要上
#include<iostream> #include<cstring> using namespace std; /*匈牙利演算法,二分圖匹配,杭電2063題*/ int k,m,n; //k為組合數,m為左側數,n為右側點數 bool vis[520]; //這個右側點是否被找過 int line[520][520]; //line表示左側女生和右側男生是否相互喜歡 int peidui[520]; //peidui表示右側男生匹配到的左側女生的點 bool find(int x) //匈牙利演算法是遞迴的 { for(int i=1;i<=n;i++) //遍歷圖的左側所有男生 { if(line[x][i]==1&&!vis[i]) //如果該右側男生沒有被訪問過,並且左側x喜歡右側i { vis[i]=true; //設定該右側男生被訪問過 if(peidui[i]==0||find(peidui[i])) //如果右側男生沒有被配對,或者右側的原配可以尋找到新的配對 { peidui[i]=x; //則該右側點匹配到該左側點 return true; //返回結果真 } } } return false; //否則返回結果假 } int main() { int ans; //最大配對數 int g,b; //g為圖的左側,b為右側 while(cin>>k&&k) //輸入組合數 { cin>>m>>n; //輸入圖左側點的個數、圖右側點的個數 memset(line,0,sizeof(line)); //初始化鄰接矩陣 memset(peidui,0,sizeof(peidui)); //初始化訪問陣列 for(int i=0;i<k;i++) { cin>>g>>b; //輸入左側點、右側點 line[g][b]=1; //g左側喜歡b右側,設定為有邊 } ans=0; for(int i=1;i<=m;i++) //遍歷所有左側點 { memset(vis,false,sizeof(vis)); //每次都需要初始化訪問陣列 if(find(i)) ans++; //如果配對成功,結果自增 } cout<<ans<<endl; //輸出結果 } }