首先判断是否为一个二分图
如果是的话用匈牙利算法来进行二分图最大匹配
匈牙利算法也就是一个dfs 递归的东西。
如果不懂的请看一篇讲的很详细的博客链接:https://www.cnblogs.com/logosG/p/logos.html
/*
qq:1239198605
ctgu_yyf
*/
#include<iostream>
#include<cstdio>
#include<string>
#include<vector>
#include<queue>
#include<stack>
#include<cstring>
#include<algorithm>
#include<cmath>
#define ll long long
using namespace std;
int n,m;
vector <int> G[205];//图的邻接表 表示
int match[205];//所匹配的顶点
int used[105];//标记数组
int color[205];
/*
bool dfsjudge(int v,int c)
{
color[v]=c;//把顶点颜色染成c
for(int i=0;i<G[v].size();i++)
{
//如果相邻的顶点同色 则返回false
if(color[G[v][i]]==c) return false;
//如果相邻顶点还没有被染色 则染成-c
if(color[G[v][i]]==0&&!dfsjudge(G[v][i],-c)) return false;
}
//如果所有顶点染过色了
return true;
}
bool judge()
{
for(int i=0;i<n;i++)
{
if(color[i]==0)
{
//如果顶点i没有被染色 则染成1
if(!dfsjudge(i,1))
{
return false;
}
}
}
return true;
}
*/
bool bfs(int s)//二分图判断
{
int que[205],rear=0,front=0;
int color[205];
memset(color,-1,sizeof(color));
color[s]=1;que[rear++]=s;
while(rear!=front)
{
int v=que[front++];
for(int i=0;i<G[v].size();i++)
{
int u=G[v][i];
if(color[u]==-1)
{
color[u]=!color[v];//若没有染色则染成相反颜色
que[rear++]=u;
}
else if(color[u]==color[v]) return false;//若相邻结点颜色相同则不是二分图
}
}
return true;
}
bool dfs(int v)
{
used[v]=1;//该男生已经被安排过
for(int i=0;i<G[v].size();i++)//在该男生喜欢的女生中去找
{
int u=G[v][i],w=match[u]; //u表示该女生 w表示该女生匹配的男生
if(w==0||!used[w]&&dfs(w)) //如果该女生还没有匹配(单身) 或者 该男生没有被安排过且该女生匹配的男生可以去喜欢其他女生
{
match[v]=u; //将这个男生和女生配对
match[u]=v;
return true; //配对成功
}
}
return false; //配对失败
}
int bipartite_matching()
{
int res=0;
memset(match,0,sizeof(match));
for(int i=1;i<=n;i++)
{
if(!match[i])//如果该男生没有匹配女生
{
memset(used,0,sizeof(used));//初始化used数组 给他安排
if(dfs(i))//如果能安排
{
res++;//对数++
}
}
}
return res;
}
int main()
{
//ios::sync_with_stdio(false);
while(cin>>n>>m)
{
//初始化邻接表
for(int i=1;i<=n;i++)
G[i].clear();
int u,v;
for(int i=0;i<m;i++)
{
cin>>u>>v;
G[u].push_back(v);
G[v].push_back(u);
}
if(bfs(1))
cout<<bipartite_matching()<<endl;
else
cout<<"No"<<endl;
}
return 0;
}