今天复习二分匹配,A 了一道模板题。

  二分匹配需要理解增广路的寻找。用dfs来更新最大匹配。注意一些点:赋初值;愚蠢地把==写成了= ; 然后match的记值;每个点都要重新走一遍。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #define INF 80005
 6 #define maxn 405
 7 using namespace std;
 8 int n,m,ans,match[maxn];
 9 int tot,he[maxn],to[INF],ne[INF];
10 bool check[maxn];
11 void add(int a,int b)
12 {
13     tot++;to[tot]=b;ne[tot]=he[a];he[a]=tot;
14 }
15 bool findway(int x)
16 {
17     for (int i=he[x];i;i=ne[i])//dfs
18     if (!check[to[i]]){
19         check[to[i]]=true;
20         if (match[to[i]]==-1||findway(match[to[i]])){  //not findway(to[i])
21             match[to[i]]=x;//<qwq> == not =
22             return true;
23         }
24     }
25     return false;
26 }
27 int KM ()//hungray
28 {
29     ans=0;
30     memset(match,-1,sizeof (match));
31     for (int i=1;i<=n;i++)    //if (match[i]=-1)
32     {
33         memset(check,0,sizeof (check));
34         if (findway(i)) ans++;
35     }
36     return ans;
37 }
38 int main()
39 {
40     freopen("poj1274.in","r",stdin);
41     while (cin>>n>>m){
42         memset(ne,0,sizeof(ne));
43         memset(to,0,sizeof (to));
44         memset(he,0,sizeof (he));
45         tot=0;//赋初值 
46         for (int i=1;i<=n;i++)
47         {
48             int a;scanf("%d",&a);
49             for (int j=1;j<=a;j++)
50             {
51                 int b;scanf("%d",&b);
52                 b+=n;//!!!
53                 add(i,b);add(b,i);
54             }
55         }
56         printf("%d\n",KM());
57     }
58     return 0;
59 }

 

 posted on 2016-10-11 20:28  qzgxlx  阅读(184)  评论(0编辑  收藏  举报