题意:
n个学生要分成两个队伍,每个队伍人数相同,每个人都有一定的敌人(不超过2个),不能跟敌人分在一组,问至少踢掉多少人才能满足条件
思路:
二分图染色模板题,因为每个人最多只有2个敌人(最多只有2条边),所以只看奇数环的个数也是可以的,需要注意的是每个队伍的人数要相同,所以踢掉一些人后还要看剩下的个数是不是奇数.(代码中的color数组既表示颜色又表示是否被访问过)
#include <bits/stdc++.h>
#define mem(a,b) memset(a,b,sizeof(a))
#define rep(i,a,b) for(int i=a;i<b;i++)
#define debug(a) printf("a =: %d\n",a);
const int INF=0x3f3f3f3f;
const int maxn=1e6+50;
const int Mod=1e9+7;
typedef long long ll;
using namespace std;
int n,m;
vector<int> G[maxn];
int color[maxn];
int bfs(int st){
int ans=0;
queue<int> qu;
qu.push(st);
color[st]=0;
while(!qu.empty()){
int t=qu.front();
qu.pop();
int sz=G[t].size();
for (int i=0;i<sz;i++){
if (color[G[t][i]]>=0 && color[G[t][i]]+color[t]!=1) ans++;
if (color[G[t][i]]==-1){
color[G[t][i]]=!color[t];
qu.push(G[t][i]);
}
}
}
return ans;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
#endif
while(scanf("%d %d",&n,&m)!=EOF){
for (int i=0;i<=n;i++) G[i].clear();
int u,v;
for (int i=0;i<m;i++){
scanf("%d %d",&u,&v);
G[u].push_back(v);
G[v].push_back(u);
}
mem(color,-1);
int sum=0;
for (int i=1;i<=n;i++){
if (color[i]==-1) sum+=bfs(i);
}
n-=sum/2;
// printf("%d %d==\n",sum/2,n);
printf("%d\n",sum/2+(n&1));
}
return 0;
}