题意:
给出一些学生的认识情况,比如A和B认识,B和C认识,但是A和C不一定认识。现在问能否将这些学生分成两个组,并且每组中的学生互相不认识,如果能分,求出最大能匹配的学生对数。
题解:
首先bfs判断是否是二分图,然后求二分最大匹配。
#include<iostream>
#include<math.h>
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<vector>
#include<queue>
#include<map>
#include<set>
#define B(x) (1<<(x))
using namespace std;
typedef long long ll;
void cmax(int& a,int b){ if(b>a)a=b; }
void cmin(int& a,int b){ if(b<a)a=b; }
void cmax(ll& a,ll b){ if(b>a)a=b; }
void cmin(ll& a,ll b){ if(b<a)a=b; }
void add(int& a,int b,int mod){ a=(a+b)%mod; }
void add(ll& a,ll b,ll mod){ a=(a+b)%mod; }
const int oo=0x3f3f3f3f;
const int MOD=1000000007;
const int maxn=205;
int n;
int g[maxn][maxn],vis[maxn],mat[maxn];
int cor[maxn];
bool jud(){
queue<int>q;
memset(cor,-1,sizeof cor);
cor[1]=1;
q.push(1);
while(!q.empty()){
int u=q.front();q.pop();
for(int v=1;v<=n;v++)if(g[u][v]){
if(cor[v]==-1){
cor[v]=1-cor[u];
q.push(v);
}else if(cor[u]==cor[v])return false;
}
}
return true;
}
int dfs(int u){
for(int i=1;i<=n;i++){
if(g[u][i]&&!vis[i]){
vis[i]=1;
if(mat[i]==-1||dfs(mat[i])){
mat[i]=u;
return 1;
}
}
}
return 0;
}
int Match(){
memset(mat,-1,sizeof mat);
int ans=0;
for(int i=1;i<=n;i++){
memset(vis,0,sizeof vis);
ans+=dfs(i);
}
return ans;
}
int main(){
//freopen("E:\\read.txt","r",stdin);
int m,u,v;
while(scanf("%d %d",&n,&m)!=EOF){
memset(g,0,sizeof g);
for(int i=1;i<=m;i++){
scanf("%d %d",&u,&v);
g[u][v]=1;
g[v][u]=1;
}
if(!jud()){
printf("No\n");
continue;
}
printf("%d\n",Match()/2);
}
return 0;
}