hdu 2444 The Accomodation of Students(二分图判断+求最大匹配)
2014-06-09 14:39
603 查看
题意:有一群小朋友,其中一部分小朋友互相认识,给出小朋友之间是否认识的关系。首先判断是否能将所有小朋友分成两组,每组中任意两个人都不认识。如果能的话,将两个认识的小朋友分成一组,问最多能分多少组?
思路:首先是对图进行染色,判断是否能将图分成两个部分,如果不能的话,直接输出“No”,否则继续计算。
求分组:求二分图最大匹配数。代码中注释的vis[i]=1这个语句开始的时候我一直没有加,当时想的是对于每一个点进行搜索的时候标记,但是这样会出现比如2的子节点为4,然后link[4]==2的循环。注意每一次搜索的是link[son],而不是son。
对于每次搜索link[son],而不是son,需要特别注意一下。寻找增广路径的过程遵循这样一个规律:对于一条路径,如果它的起始点是未盖点,同时它的最后一个点也是未盖点,那么这条路径就是一条可增广路径。比如说对于1……2——3……4这样的路径,就可以通过修改为1——2……3——4这种方式使配对增加一。而在这个过程中,如果我们检查1的子节点2,这时候如果2是盖点,我们需要的不是对2寻找一个新的配对对象(即使找到了,我们也不能把1和2连接起来,因为2已经在另一个连线中),而是对3寻找一个新的配对对象。
思路:首先是对图进行染色,判断是否能将图分成两个部分,如果不能的话,直接输出“No”,否则继续计算。
求分组:求二分图最大匹配数。代码中注释的vis[i]=1这个语句开始的时候我一直没有加,当时想的是对于每一个点进行搜索的时候标记,但是这样会出现比如2的子节点为4,然后link[4]==2的循环。注意每一次搜索的是link[son],而不是son。
对于每次搜索link[son],而不是son,需要特别注意一下。寻找增广路径的过程遵循这样一个规律:对于一条路径,如果它的起始点是未盖点,同时它的最后一个点也是未盖点,那么这条路径就是一条可增广路径。比如说对于1……2——3……4这样的路径,就可以通过修改为1——2……3——4这种方式使配对增加一。而在这个过程中,如果我们检查1的子节点2,这时候如果2是盖点,我们需要的不是对2寻找一个新的配对对象(即使找到了,我们也不能把1和2连接起来,因为2已经在另一个连线中),而是对3寻找一个新的配对对象。
#include<stdio.h> #include<string.h> #include<stdlib.h> #define N 205 #define M 40005 struct node { int son; int next; } Edge[M*2]; int head ,vis ,q ,link ; int n,m,cnt; void AddEdge(int x,int y) { Edge[cnt].son=y; Edge[cnt].next=head[x]; head[x]=cnt++; Edge[cnt].son=x; Edge[cnt].next=head[y]; head[y]=cnt++; return ; } int bfs(int k) { int h,t; h=t=0; q[t++]=k; vis[k]=0; while(h!=t) { int cur=q[h++]; int u=head[cur]; for(int i=u; i!=-1; i=Edge[i].next) { int son=Edge[i].son; if(vis[son]!=-1&&vis[son]!=(vis[cur]+1)%2) return 1; else if(vis[son]!=-1) continue; vis[son]=(vis[cur]+1)%2; q[t++]=son; } } return 0; } int dfs(int father) { int u=head[father]; vis[father]=1; for(int i=u; i!=-1; i=Edge[i].next) { int son=Edge[i].son; if(vis[son]) continue; vis[son]=1;///开始的时候没有加上这个标记。 if(link[son]==-1||dfs(link[son])==1) { link[son]=father; return 1; } } return 0; } int main() { while(scanf("%d%d",&n,&m)!=EOF) { memset(head,-1,sizeof(head)); cnt=0; for(int i=1; i<=m; i++) { int x,y; scanf("%d%d",&x,&y); AddEdge(x,y); } memset(vis,-1,sizeof(vis)); int flag=0; for(int i=1; i<=n; i++) { if(vis[i]==-1) { flag=bfs(i); if(flag) break; } } if(flag) { printf("No\n"); continue; } memset(link,-1,sizeof(link)); int count=0; for(int i=1; i<=n; i++) { memset(vis,0,sizeof(vis)); if(dfs(i)) count++; } printf("%d\n",count/2); } return 0; }
相关文章推荐
- HDU-2444 The Accomodation of Students(二分图判断+最大二分匹配)
- hdu 2444 The Accomodation of Students(二分图判断,二分图最大匹配)
- HDU - 2444 The Accomodation of Students(二分图判断+最大匹配)
- The Accomodation of Students HDU - 2444(最大二分匹配+染色法判断二分图)
- HDU 2444 The Accomodation of Students (判断是否是二分图,然后求最大匹配)
- hdu 2444 The Accomodation of Students(最大匹配 + 二分图判断)
- hdu 2444 The Accomodation of Students(判断二分图,二分图最大匹配)
- HDU 2444 The Accomodation of Students【二分图判断+最大匹配】
- HDU 2444 The Accomodation of Students 判断二分图 + 最大匹配
- hdu 2444 The Accomodation of Students (判断二分图,二分图最大匹配)
- HDU 2444 The Accomodation of Students(判断是否为二分图+最大匹配)
- HDU 2444 The Accomodation of Students(判断是否是二分图及求最大匹配)
- 【二分图判断 && 二分图最大匹配】HDU - 2444 The Accomodation of Students
- HDU 2444 The Accomodation of Students(判断二分图+最大匹配)
- hdu 2444 The Accomodation of Students 二分图判断 + 最大匹配
- HDU 2444 The Accomodation of Students(二分图判断+最大匹配)
- hdu 2444 The Accomodation of Students (判断二分图+最大匹配)
- HDU 2444 The Accomodation of Students(二分图判断+最大二分匹配)
- HDU 2444 The Accomodation of Students 二分图的判断与匹配
- HDU 2444 The Accomodation of Students——二分图判定+最大匹配