/*655.二分图-安排房间 (10分)
C时间限制:3000 毫秒 | C内存限制:3000 Kb
题目内容:
有一群学生,他们之间有的认识有的不认识。
现在要求把学生分成2组,其中同一个组的人相互不认识。如果你分成功了,那么就安排双人间,安排的规矩
是两个人分别属于不同的组,并且认识。
输入描述
首先输入两个整数n,m,表示有n个学生, m个认识对
随后m行表示认识的学生对。
输出描述
如果不能分组成功则输出“No”
否则输出有多少个房间安排学生配对。
输入样例
4 4
1 2
1 3
1 4
2 3
6 5
1 2
1 3
1 4
2 5
3 6
输出样例
No
3
*/
#include<iostream> #include<stdio.h> #include<queue> #include<vector> #include<string.h> using namespace std; const int maxn = 205; int n,m,color[maxn]; vector<int>G[maxn]; int match[maxn]; bool used[maxn]; void addedge(int a,int b){ G[a].push_back(b); G[b].push_back(a); } bool dfs(int v){ used[v] = 1; for(int i=0;i<G[v].size();i++){ int u = G[v][i],w = match[u]; if(w<0||!used[w]&&dfs(w)){ match[v] = u; match[u] = v; return 1; } } return 0; } int matching(int n){ int res = 0; memset(match,-1,sizeof(match)); for(int v = 1;v<=n;v++){ if(match[v]<0){ memset(used,0,sizeof(used)); if(dfs(v)) res++; } } return res; } bool is(){ queue<int>q; memset(color,0,sizeof(color)); q.push(1); color[1] = 1; while(!q.empty()){ int p=q.front(); q.pop(); for(int i=0;i<G[p].size();i++){ if(color[G[p][i]]==color[p]) return 0; else{ if(!color[G[p][i]]){ color[G[p][i]] = 3-color[p]; q.push(G[p][i]); } } } } return 1; } int main(){ while(cin>>n>>m){ int a,b; for(int i=0;i<m;i++){ scanf("%d%d",&a,&b); addedge(a,b); } if(!is()||n==1) cout<<"No"<<endl; else{ cout<<matching(n)<<endl; } for(int i=0;i<maxn;i++) G[i].clear(); } return 0; }