HDU-2444 The Accomodation of Students(二分图判断+最大二分匹配)

来源:互联网 发布:js实现excel上传文件 编辑:程序博客网 时间:2024/06/05 23:55

B - The Accomodation of Students
Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u
Submit Status Practice HDU 2444

Description

There are a group of students. Some of them may know each other, while others don't. For example, A and B know each other, B and C know each other. But this may not imply that A and C know each other. 

Now you are given all pairs of students who know each other. Your task is to divide the students into two groups so that any two students in the same group don't know each other.If this goal can be achieved, then arrange them into double rooms. Remember, only paris appearing in the previous given set can live in the same room, which means only known students can live in the same room. 

Calculate the maximum number of pairs that can be arranged into these double rooms. 

Input

For each data set: 
The first line gives two integers, n and m(1<n<=200), indicating there are n students and m pairs of students who know each other. The next m lines give such pairs. 

Proceed to the end of file. 

Output

If these students cannot be divided into two groups, print "No". Otherwise, print the maximum number of pairs that can be arranged in those rooms. 

Sample Input

4 41 21 31 42 36 51 21 31 42 53 6

Sample Output

No3

F。判断二分图可以使用BFS+染色即任选一个节点染白色进行BFS,如果出现遍历到的颜色与前一节点颜色一样,那就能够判断非二分图,由于存在回路的长度为偶数;否则就是二分图。

二分图的充分必要条件

  无向图G为二分图的充分必要条件是,G至少有两个顶点,且其所有回路的长度均为偶数。
  证 先证必要性。
  设G为二分图<X,E,Y>。由于X,Y非空,故G至少有两个顶点。若C为G中任一回路,令
  C = ( v0,v 1,v2,…,v l-1,v l = v0 )
  其中诸vi ( i = 0,1,…,l )必定相间出现于X及Y中,不妨设
  {v0,v2,v4,…, v l = v0} &Iacute; X
  {v1,v3,v5,…, v l-1} &Iacute; Y
  因此l必为偶数,从而C中有偶数条边。
  再证充分性。
  设G的所有回路具有偶数长度,并设G为连通图(不失一般性,若G不连通,则可对G的各连通分支作下述讨论)。
  令G的顶点集为V,边集为E,现构作X,Y,使<X,E,Y> = G。取v0&Icirc;V,置
  X = {v | v= v0或v到v0有偶数长度的通路}
  Y = V-X
  X显然非空。现需证Y非空,且没有任何边的两个端点都在X中或都在Y中。
  由于|V|≥2并且G为一连通图,因此v0必定有相邻顶点,设为v1,那么v1&Icirc;Y;故Y不空。
  设有边(u, v), 使u&Icirc;X,v&Icirc;X。那么,v0到u有偶数长度的通路,或u = v0;v0到v有偶数长度的通路,或v = v0。无论何种情况,均有一条从v0到v0的奇数长度的闭路径,因而有从v0到v0的奇数长度的回路(因从闭路径上可能删去的回路长度总为偶数),与题设矛盾。故不可能有边(u, v)使u, v均在X中。
  “没有任何边的两个端点全在Y中”的证明可仿上进行。
#include<stdio.h>#include<string.h>#include<stdlib.h>#include<limits.h>#include<queue>#include<math.h>#include<algorithm>using namespace std;#define maxn 205int n,m;int graph[maxn][maxn];int mp[maxn][maxn];int linker[maxn];bool vis[maxn];int color[maxn];//染色数组bool dfs(int u){for(int i=1;i<=n;i++){if(graph[u][i] && !vis[i]){vis[i]=1;if(!linker[i] || dfs(linker[i])){linker[i]=u;return 1;}}}return 0; }  bool bfs(int s) { queue<int>q; color[s]=0; q.push(s); while(!q.empty()) { int u=q.front(); q.pop(); for(int i=1;i<=n;i++) { if(graph[u][i]) { if(color[i]==-1)//未染色  { color[i]=!color[u]; q.push(i); } else if(color[i]==color[u])     return 0; }  }  } return 1; }int  main(){while(scanf("%d%d",&n,&m)!=EOF){memset(graph,0,sizeof(graph));memset(color,-1,sizeof(color));for(int i=1;i<=m;i++){int u,v;scanf("%d%d",&u,&v);graph[u][v]=graph[v][u]=1;} bool flag=0;for(int i=1;i<=n;i++){if(color[i]!=-1)    continue;//已染色if(!bfs(i)){     flag=1;      break;     }}if(flag){printf("No\n");continue;}memset(linker,0,sizeof(linker));int ans=0;for(int i=1;i<=n;i++){memset(vis,0,sizeof(vis));if(dfs(i))     ans++;}printf("%d\n",ans/2);}}

0 0
原创粉丝点击