题意
先判断是否能构成二分图,再计算最大匹配
思路
判断:染色法
最大匹配:匈牙利算法
AC代码
#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;
const int N = 205;
vector<int> edge[N];
int V, E;
int match[N], vis[N], col[N];
bool bfs(int s) {//染色法 bfs写法
queue<int> q;
memset(col, 0, sizeof col);
q.push(s);
col[s] = 1;
while (!q.empty()) {
int x = q.front();
q.pop();
for (int i = 0; i < edge[x].size(); i++) {
int y = edge[x][i];
if (col[y] == 0) {
col[y] = 1 ^ col[x];
q.push(y);
} else if (col[x] == col[y])
return false;
}
}
return true;
}
bool dfs(int u) {
vis[u] = 1;
for (int i = 0; i < edge[u].size(); i++) {
int v = edge[u][i], w = match[v];
if (w == 0 || (!vis[w] && dfs(w))) {
match[u] = v;
match[v] = u;
return true;
}
}
return false;
}
int matching() {
memset(match, 0, sizeof match);
int ans = 0;
for (int i = 1; i <= V; i++) {
if (!match[i]) {
memset(vis, 0, sizeof vis);
if (dfs(i))
ans++;
}
}
return ans;
}
int main() {
while (scanf("%d%d", &V, &E) != EOF) {
memset(edge, 0, sizeof edge);
for (int i = 0; i < E; i++) {
int u, v;
scanf("%d%d", &u, &v);
edge[u].push_back(v);
edge[v].push_back(u);
}
if (bfs(1))
printf("%d\n", matching());
else
printf("No\n");
}
return 0;
}