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 }

 

posted on 2016-06-06 22:01  pb2016  阅读(154)  评论(0编辑  收藏  举报