分析:求是否是二分图,若是,求最大匹配数
讲当前点染色,然后将与它相邻的点染成另一种颜色,判断相邻两个点是否有颜色相同的,有则不是二分图
#include <iostream>
#include<cstdio>
#include<cstring>
#define maxn 250
#include<queue>
using namespace std;
int k,n,m,w[maxn][maxn];
int linker[maxn];
int p[maxn],flag;
int vis[maxn];
bool used[maxn];
bool dfs(int u)
{
int v;
for(v=1;v<=n;v++)
if(w[u][v]&&!used[v])
{
used[v]=true;
if(linker[v]==-1||dfs(linker[v]))
{
linker[v]=u;
return true;
}
}
return false;
}
void bfs(int x)
{
queue<int> q;
q.push(x);
int now;
while(!q.empty())
{
now=q.front();
q.pop();
k=1-k;
for(int i=1;i<=n;i++)
{
if(w[now][i]&&i!=now)
{
if(!vis[i])
{
vis[i]=1;
p[i]=k;
q.push(i);
}
else
{
if(p[i]==p[now])
{flag=1;
// for(int j=1;j<=n;j++)
// cout<<p[j]<<' ';
// cout<<now<<' '<<i<<' '<<p[i]<<' '<<p[now]<<endl;
}
}
}
}
}
}
int hungary()
{
int res=0;
int u=0;
memset(linker,-1,sizeof(linker));
for(u=1;u<=n;u++)
{
memset(used,0,sizeof(used));
if(dfs(u))
res++;
}
return res;
}
int main()
{
int i,j;
while(scanf("%d%d",&n,&m)!=EOF)
{
memset(w,0,sizeof(w));
memset(vis,0,sizeof(vis));
while(m--)
{
scanf("%d%d",&i,&j);
w[i][j]=1;
}
flag=0;
for(i=1;i<=n;i++)
{
if(!vis[i])
{
vis[i]=1;
k=0;
p[i]=k;
bfs(i);
}
if(flag)
break;
}
if(flag)
printf("No\n");
else
printf("%d\n",hungary());
}
return 0;
}