[poj3692]Kindergarten

最大团=反图的最大独立集,而反图又恰好是一张二分图,根据二分图的最大独立集=n-最大匹配就可以做了。

 1 #include<cstdio>
 2 #include<cstring>
 3 #define N 405
 4 struct ji{
 5     int nex,to;
 6 }edge[N*N];
 7 int E,t,n,m,k,x,y,ans,head[N],vis[N],flag[N],a[N][N];
 8 void add(int x,int y){
 9     edge[E].nex=head[x];
10     edge[E].to=y;
11     head[x]=E++;
12 }
13 bool dfs(int k){
14     if (vis[k])return 0;
15     vis[k]=1;
16     for(int i=head[k];i!=-1;i=edge[i].nex){
17         int v=edge[i].to;
18         if ((!flag[v])||(dfs(flag[v]))){
19             flag[v]=k;
20             flag[k]=v;
21             return 1;
22         }
23     }
24     return 0;
25 }
26 int main(){
27     while (scanf("%d%d%d",&n,&m,&k)!=EOF){
28         if ((!n)&&(!m)&&(!k))return 0;
29         memset(a,0,sizeof(a));
30         E=0;
31         memset(head,-1,sizeof(head));
32         for(int i=1;i<=k;i++){
33             scanf("%d%d",&x,&y);
34             a[x][y]=1;
35         }
36         for(int i=1;i<=n;i++)
37             for(int j=1;j<=m;j++)
38                 if (!a[i][j])add(i,j+n);
39         ans=n+m;
40         memset(flag,0,sizeof(flag));
41         for(int i=1;i<=n;i++){
42             memset(vis,0,sizeof(vis));
43             if (!flag[i])ans-=dfs(i);
44         }
45         printf("Case %d: %d\n",++t,ans);
46     }
47 }
View Code

 

posted @ 2019-07-28 10:26  PYWBKTDA  阅读(92)  评论(0编辑  收藏  举报