这题很好的运用了二分图补图的性质
二分图补图的两个 部分就是 两个最大团
因为是两个班的学生那么我们一定可以将图分成一个二分图
此题是找补图的二分匹配 因为补图的两个部分都是团 所以只要找到二分图的两个部分就好
若两个部分 有一个为奇数 那么 输出答案 n / 2
若两个都为奇数 那我们必须找到班与班之间 一组人匹配 其他的自己班里匹配
那我们染色法就好了
#include<iostream>
#include<vector>
#define endl "\n"
using namespace std;
const int N = 1e5 + 10,M = 4e5 + 10;
vector<int>v[N];
void add(int a,int b){
v[a].push_back(b);
}
int cnt[5];
int col[N];
void dfs(int x){
for(auto j : v[x]){
if(!col[j]){
col[j] = col[x] ^ 1;
cnt[col[j]]++;
dfs(j);
}
}
}
int main(){
int n,m;
scanf("%d%d",&n,&m);
for(int i = 1; i <= m; i++){
int x,y;
scanf("%d%d",&x,&y);
add(x,y),add(y,x);
}
for(int i = 1; i <= n; i++){
if(!col[i]){
col[i] = 2;
cnt[col[i]]++;
dfs(i);
}
}
if(cnt[2] % 2 == 0 || cnt[3] % 2 == 0){
cout << n / 2 << endl;
}else{
for(int i = 1; i <= n; i++){
if(v[i].size() != cnt[col[i] ^ 1]){
cout << n / 2 << endl;
return 0;
}
}
cout << n / 2 - 1 << endl;
}
return 0;
}