1. 程式人生 > >51nod 2006 飛行員配對(二分圖最大匹配) 裸匈牙利算法 求二分圖最大匹配題

51nod 2006 飛行員配對(二分圖最大匹配) 裸匈牙利算法 求二分圖最大匹配題

spa 解法 tor != cto == 遇到 由於 include

題目:

技術分享

題目已經說了是最大二分匹配題,

查了一下最大二分匹配題有兩種解法,

匈牙利算法和網絡流。

看了一下覺得匈牙利算法更好理解,

然後我照著小紅書模板打了一遍就過了。

匈牙利算法:先試著把沒用過的左邊的點和沒用過的右邊的點連起來,

      如果遇到一個點已經連過就試著把原來的拆掉 把現在這條線連起來看能不能多連上一條線。

總結來說就是試和拆,試的過程很簡單,拆的過程由於使用遞歸寫的,很復雜。很難講清楚,只能看代碼自己理會。

代碼(有註釋):

#include <bits\stdc++.h>
using namespace std;
typedef 
long long ll; //輸入: const int MAXN = 555; // 數組長度 int n = 200; //n表示左側的點數 vector <int> g[MAXN]; // 表示與左邊點i相連的右邊點 //輸出: int from[MAXN];//表示最大匹配中與左邊點i相連的邊 int tot; // 二分圖最大匹配數 bool use[MAXN]; // 左邊點的使用標記 //匈牙利算法 模板題 ,match和hungary見小紅書ACM國際大學生程序設計競賽 算法與實現 bool match(int x){ for(int i = 0;i < g[x].size(); ++i){
if(!use[g[x][i]]){ use[g[x][i]] = true; if(from[g[x][i]] == -1 || match(from[g[x][i]])){ from[g[x][i]] = x; return true; } } } return false; } int hungary(){ tot = 0; memset(from,255,sizeof(from)); for(int
i = 1;i <= n; i++){ memset(use,0,sizeof(use)); if(match(i)) ++tot; } return tot; } int main() { int m; cin >> n >> m; int k1,k2; cin >> k1 >> k2; while(k1 != -1||k2 != -1){ g[k1].push_back(k2-n); cin >> k1 >> k2; }; cout << hungary() << endl; return 0; }

51nod 2006 飛行員配對(二分圖最大匹配) 裸匈牙利算法 求二分圖最大匹配題