这道题要先判断图是不是二分图,如果不是的话,就直接输出No,是的话就求最大匹配,
建边是双向的所以要/2
判断二分图:对点进行染色,如果A与B认识,A,B的颜色要不同,
如果出现颜色相同的就矛盾了,就不是二分图
#include<stdio.h> #include<string.h> #include<queue> #define N 210 using namespace std; int map[N][N],color[N],vis[N],match[N],n,m; int find(int x) { for(int i=1;i<=n;i++) { if(vis[i]==0&&map[x][i]==1) { vis[i]=1; if(match[i]==-1||find(match[i])==1) { match[i]=x; return 1; } } } return 0; } int judgecolor() { int cur; queue<int>Q; Q.push(1); while(!Q.empty()) { cur=Q.front(); Q.pop(); for(int i=1;i<=n;i++) { if(map[cur][i]==1) { if(color[i]==-1) { color[i]=1-color[cur]; Q.push(i); } else if(color[i]==color[cur]) return 0; } } } return 1; } int main() { int i,x,y,sum; while(scanf("%d%d",&n,&m)!=-1) { memset(map,0,sizeof(map)); memset(color,-1,sizeof(color)); memset(match,-1,sizeof(match)); for(i=0;i<m;i++) { scanf("%d%d",&x,&y); map[x][y]=map[y][x]=1; } if(judgecolor()==0) { printf("No "); continue; } sum=0; for(i=1;i<=n;i++) { memset(vis,0,sizeof(vis)); sum+=find(i); } printf("%d ",sum/2); } return 0; }