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 }
时间: 2024-10-12 20:55:27