大意:给n个关系,其中有m对人是相互认识的,如果能把这n个人分成两组,每组内的人相互不认识,则问最大匹配数是多少
思路:看懂题的话就是二分图裸题,但一开始要先判断是否是二分图,用bfs染色
代码:
#include<bits/stdc++.h>
#define maxn 205
using namespace std;
vector<int>edge[maxn];
int n,m;
int vis[maxn],match[maxn];
bool bfs(int s){//判断是否为二分图
int color[maxn];
queue<int> que;
memset(color,-1,sizeof color);
que.push(s);
color[s]=1;
while(!que.empty()){
int now=que.front();
que.pop();
for(int i=0;i<edge[now].size();i++){
int v=edge[now][i];
if(color[v]==-1){
color[v]=!color[now];
que.push(v);
}
if(color[v]==color[now]){
return false;
}
}
}
return true;
}
bool dfs(int u){
for(int i=0;i<edge[u].size();i++){
int v=edge[u][i];
if(!vis[v]){
vis[v]=1;
if(match[v]==0||dfs(match[v])){
match[v]=u;
return true;
}
}
}
return false;
}
int find(){
int sum=0;
memset(match,0,sizeof match);
for(int i=1;i<=n;i++){
memset(vis,0,sizeof vis);
if(dfs(i)){
sum++;
}
}
return sum;
}
int main(){
// freopen("in.txt","r",stdin);
while(~scanf("%d%d",&n,&m)){
for(int i=0;i<maxn;i++){
edge[i].clear();
}
for(int i=0;i<m;i++){
int x,y;
scanf("%d%d",&x,&y);
edge[x].push_back(y);
edge[y].push_back(x);
}
if(!bfs(1)||n==1){
printf("No\n");
continue;
}
printf("%d\n",find()/2);//除2是因为对称,1认识2,2认识1,属同一情况
}
return 0;
}