题目含义
给出很多一对数,代表这两个人认识
要你将这些人分成两堆,一堆中的人互不认识(就是判定无负环)
如果可以的话,问最大匹配
题目分析
二分图染色模板题
注意这里二分代表的两个集合都是n个学生,如果你建双向边,最后最大匹配数要除2
题目代码
#include<iostream> #include<stdio.h> #include<string.h> #include<queue> using namespace std; typedef long long LL; const int maxn=4e4+7; struct edge{ int to,next; }e[maxn]; int head[207],tot,person[207]; bool vis[207]; void add(int u,int v){ e[tot].to=v; e[tot].next=head[u]; head[u]=tot++; } int n,m,a,b; void init(){ tot=0; memset(head,-1,sizeof(head)); memset(person,0,sizeof(person)); } bool bfs(){ queue<int>q; bool col[207]; q.push(1); col[1]=vis[1]=true; while(!q.empty()){ int u=q.front();q.pop(); for(int i=head[u];i!=-1;i=e[i].next){ int v=e[i].to; if(!vis[v]){ vis[v]=true; col[v]=!col[u]; q.push(v); } else { if(col[v]==col[u])return false; } } }return true; } bool find(int u){ for(int i=head[u];i!=-1;i=e[i].next){ int v=e[i].to; if(vis[v])continue; vis[v]=true; if(!person[v]||find(person[v])){ person[v]=u;return true; } }return false; } int main(){ while(~scanf("%d%d",&n,&m)){ init(); for(int i=1;i<=m;i++){ scanf("%d%d",&a,&b); add(a,b); } if(!bfs())printf("No\n"); else{ int sum=0; for(int i=1;i<=n;i++){ memset(vis,false,sizeof(vis)); if(find(i))sum++; } printf("%d\n",sum); } } return 0; }