思路:模拟分组,如果一个点的分组与上一次的分组矛盾则输出No,否则对两组进行匹配。
代码:
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#define Maxn 205
#define clr(a,b) memset(a,b,sizeof(a))
using namespace std;
int c[Maxn],s[Maxn],kx[Maxn*Maxn],ky[Maxn*Maxn],g[Maxn][Maxn];
int n,m,nx,ny,mat[Maxn],vis[Maxn],x,y;
bool find(int u)
{
for(int i=1;i<=ny;i++)
{
if(!vis[i]&&g[u][i])
{
vis[i]=1;
if(mat[i]==-1||find(mat[i]))
{
mat[i]=u;
return 1;
}
}
}
return 0;
}
int Hungary()
{
int Max=0;
clr(mat,-1);
for(int i=1;i<=nx;i++)
{
clr(vis,0);
if(find(i))
Max++;
}
return Max;
}
int main()
{
int n,m;
while(~scanf("%d %d",&n,&m))
{
int flag=1;clr(s,0);
for(int i=1;i<=m;i++)
{
scanf("%d %d",&x,&y);
if(flag)
{
if(!s[x]&&!s[y]) s[x]=1,s[y]=2;
if(s[x]!=0&&!s[y]) s[y]=3-s[x];
if(!s[x]&&s[y]!=0) s[x]=3-s[y];
if(s[x]==s[y]) flag=0;
}
kx[i]=x;
ky[i]=y;
}
if(!flag)
{
printf("No\n");
continue;
}
nx=0;
ny=0;
clr(c,0);
clr(g,0);
for(int i=1;i<=m;i++)
{
if(s[kx[i]]==1)
{
if(!c[kx[i]]) c[kx[i]]=++nx;
if(!c[ky[i]]) c[ky[i]]=++ny;
g[c[kx[i]]][c[ky[i]]]=1;
}
else
{
if(!c[kx[i]]) c[kx[i]]=++ny;
if(!c[ky[i]]) c[ky[i]]=++nx;
g[c[ky[i]]][c[kx[i]]]=1;
}
}
printf("%d\n",Hungary());
}
return 0;
}