典型的二分图匹配,首先要判断是否为二分图 用染色法,
然后就是匈牙利算法。
#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
using namespace std;
typedef long long LL;
const int M = 210;
struct node
{
int from,to,next;
} edge[210*210];
int headlist[M];
int match[M];
int vis[M];
int cnt;
int color[M];
void add(int a,int b)
{
edge[cnt].from=a;
edge[cnt].to=b;
edge[cnt].next=headlist[a];
headlist[a]=cnt++;
}
int bfs()
{
int i,v;
queue<int>q;
memset(color,-1,sizeof(color));
color[1]=1;
q.push(1);
while(!q.empty())
{
int now=q.front();
q.pop();
for(i=headlist[now]; ~i ; i=edge[i].next)
{
v=edge[i].to;
if(color[v]==-1)
{
color[v]=~color[now];
q.push(v);
}
if(color[v]==color[now])
return 1;
}
}
return 0;
}
int dfs(int k)
{
int i,j,v;
for(i=headlist[k]; ~i; i=edge[i].next)
{
j=edge[i].to;
if(vis[j])
continue;
vis[j]=1;
if(match[j]==-1 || dfs(match[j]))
{
match[j]=k;
return 1;
}
}
return 0;
}
int main()
{
//freopen("in.txt","r",stdin);
int n,m;
int i;
while(scanf("%d%d",&n,&m)!=-1)
{
cnt=0;
memset(headlist,-1,sizeof(headlist));
for(i=0; i<m; ++i) //无向图建立邻接表
{
int a,b;
cin>>a>>b;
add(a,b);
add(b,a);
}
if(bfs()) //染色法 判断是否为二分图
{
cout<<"No"<<endl;
continue;
}
int ans=0;
memset(match,-1,sizeof(match));
for(i=1; i<=n; ++i)
{
memset(vis,0,sizeof(vis));
ans+=dfs(i);
}
cout<<ans/2<<endl;
}
return 0;
}