1 /******************************************************** 2 题目: Asteroids(poj 3041) 3 题意: 矩阵上有一些小行星,占据了一些格子,我们每次操 4 作可以清理一列中的所有小行星,也可以清理一行中 5 的所有小行星,问最少进行多少次操作可以清理掉所 6 有的小行星。 7 算法: 二分图匹配 8 思路: 以矩阵的行和列分别为一个集合,有小行星的点连接 9 两个集合,这样就构成以个二分图了,然后只要带模板 10 就可以了。 11 **********************************************************/ 12 #include<iostream> 13 #include<cstdio> 14 #include<cstring> 15 #include<algorithm> 16 #include<vector> 17 using namespace std; 18 19 const int mx=505; 20 vector<int>map[mx],g; 21 int vs[mx],father[mx]; 22 23 24 ///二分图模板 25 int dfs(int u) 26 { 27 for (int i=0;i<map[u].size();i++) 28 { 29 int v=map[u][i]; 30 if (!vs[v]) 31 { 32 vs[v]=1; 33 if (father[v]==-1||dfs(father[v])) 34 { 35 father[v]=u; 36 return 1; 37 } 38 } 39 } 40 return 0; 41 } 42 43 int main() 44 { 45 int n,k; 46 scanf("%d%d",&n,&k); 47 g.clear(); 48 for (int i=1;i<=n;i++) map[i].clear(); 49 int u,v; 50 memset(vs,0,sizeof(vs)); 51 while (k--) 52 { 53 scanf("%d%d",&u,&v); 54 if (!vs[u]) g.push_back(u); 55 map[u].push_back(v); 56 vs[u]=1; 57 } 58 int ans=0; 59 memset(father,-1,sizeof(father)); 60 for (int i=0;i<g.size();i++) 61 { 62 memset(vs,0,sizeof(vs)); 63 if (dfs(g[i])) ans++; 64 } 65 printf("%d\n",ans); 66 }