题意:n,m。n个人,m个关系。
m行关系,ab之间认识。
求这个图是不是个二分图。二分图的定义是,一条边中的两个端点分属于不同的点集,这就意味着所有互相认识的人都在不同的阵营,所以在同一阵营的都互相不认识。
判断是否是二分图可以用DNA交叉染色法,BFSDFS都行。
如果可以构成二分图的话,求最大匹配边,也就是说,最多能够匹配多少对。
直接上板子223333
#include <iostream> #include <cstdio> #include <cstring> #include <queue> #include <string.h> using namespace std; int n,m,cnt; struct node { int to,next; } edge[50000]; int head[205],color[205]; int vis[205],match[205]; int dfs(int k) { int v; for(int j=head[k]; j!=-1; j=edge[j].next) { v=edge[j].to; if(vis[v]) { continue; } vis[v]=1; if(match[v]==-1||dfs(match[v])) { match[v]=k; return 1; } } return 0; } void add(int a,int b) { edge[cnt].to=b; edge[cnt].next=head[a]; head[a]=cnt++; } int Color() { int v; queue<int>q; int now,c_next; memset(color,-1,sizeof(color)); color[1]=1; q.push(1); while(!q.empty()) { now=q.front(); q.pop(); c_next=1-color[now]; for(int j=head[now]; j!=-1; j=edge[j].next) { v=edge[j].to; if(color[v]==-1) { color[v]=c_next; q.push(v); } else if(color[v]==color[now]) { return 1; } } } return 0; } int main() { int a,b,ans; while(~scanf("%d%d",&n,&m)) { cnt=0; memset(head,-1,sizeof(head)); for(int i = 0; i < m; ++i) { scanf("%d%d",&a,&b); add(a,b); add(b,a); } if(Color()) { printf("No "); continue; } ans=0; memset(match,-1,sizeof(match)); for(int i=1; i<=n; i++) { memset(vis,0,sizeof(vis)); ans+=dfs(i); } printf("%d ",ans/2); } return 0; }