二分图最大匹配(匈牙利算法) POJ 3041 Asteroids

 

题目传送门

 1 /*  2  题意:每次能消灭一行或一列的障碍物,要求最少的次数。  3  匈牙利算法:把行和列看做两个集合,当有障碍物连接时连一条边,问题转换为最小点覆盖数==二分图最大匹配数  4  趣味入门:http://blog.csdn.net/dark_scope/article/details/8880547  5 */  6 #include <cstdio>  7 #include <algorithm>  8 #include <cstring>  9 #include <vector> 10 using namespace std; 11 12 const int MAXN = 5e2 + 10; 13 const int INF = 0x3f3f3f3f; 14 vector<int> G[MAXN]; 15 bool vis[MAXN]; 16 int lk[MAXN]; 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 (lk[v] == -1 || DFS (lk[v])) 27  { 28 lk[v] = u; return true; 29  } 30  } 31  } 32 return false; 33 } 34 35 int hungary(int n) 36 { 37 int res = 0; memset (lk, -1, sizeof (lk)); 38 for (int i=1; i<=n; ++i) 39  { 40 memset (vis, false, sizeof (vis)); 41 if (DFS (i)) res++; 42  } 43 44 return res; 45 } 46 47 int main(void) //POJ 3041 Asteroids 48 { 49 // freopen ("POJ_3041.in", "r", stdin); 50 51 int n, k; 52 while (scanf ("%d%d", &n, &k) == 2) 53  { 54 for (int i=1; i<=n; ++i) G[i].clear (); 55 for (int i=1; i<=k; ++i) 56  { 57 int x, y; scanf ("%d%d", &x, &y); 58  G[x].push_back (y); 59  } 60 61 printf ("%d\n", hungary (n)); 62  } 63 64 return 0; 65 }

 

你可能感兴趣的:(poj)