1. 程式人生 > >POJ 3041 Asteroids 二分圖之最大匹配

POJ 3041 Asteroids 二分圖之最大匹配

匹配 eof 等於 link 矩陣 class -s esp spa

題意:在一個網格中有若幹個點,每一次可以清除一行或者一列,問最少幾次可以將網格中的點全部清除。

思路:這個題是一個入門的最大匹配題(這個好像不是思路..)。一般的方式就是將 行 看作集合A,列 看作集合B。

這麽說有點抽象。舉個例子:2行3列的矩陣可以看作是集合A={1,2}與B={1,2,3},假設矩陣[1][2] 存在點(別忘了題意),則A中的元素1與B中元素2連有一條邊。

這樣就可以將題給矩陣轉化為二分圖,再利用匈牙利算法得到最大匹配數就是答案了。

 1 #include<iostream>
 2 #include<cstring>
 3 using namespace
std; 4 int n, k; 5 int v1, v2;//二分圖頂點集,都等於n 6 bool map[501][501]; 7 bool visit[501]; //記錄v2中的每個點是否被搜索過 8 int link[501]; //記錄v2中的點y在v1中所匹配的點x的編號 9 int result;//最大匹配數 10 bool dfs(int x) 11 12 { 13 for (int y = 1; y <= v2; y++) 14 { 15 if (map[x][y] && !visit[y]) 16 { 17 visit[y] = true
; 18 if (link[y] == 0 || dfs(link[y])) 19 { 20 link[y] = x; 21 return 1; 22 } 23 } 24 } 25 return 0; 26 } 27 28 //匈牙利算法hungary algorithm 29 void search() 30 { 31 for (int x = 1; x <= v1; x++) 32 { 33 34 memset(visit,false
,sizeof(visit)); 35 36 if (dfs(x)) //從v1中的節點x開始尋找增廣路徑p 37 38 result++; 39 } 40 } 41 42 int main() 43 { 44 cin >> n >> k; 45 v1 = v2 = n; 46 int x, y; 47 memset(map,0,sizeof(map)); 48 for (int i = 1; i <= k; i++) 49 { 50 cin >> x >> y; 51 map[x][y] = true; 52 } 53 search(); 54 cout << result << endl; 55 return 0; 56 }

POJ 3041 Asteroids 二分圖之最大匹配