题目链接
解题思路:
- 题目先问能不能成为二分图,那么直接用染色法判断即可
- 之后标准二分图匹配
AC代码:
#include <iostream>
#include <algorithm>
#include <cstring>
#include <stdio.h>
#include <cmath>
using namespace std;
const int maxn = 210;
const int maxm = 41000;
int n, m, tot = 1;
int color[maxn], match[maxn], vis[maxn];
int Head[maxn], Next[maxm], To[maxm];
void Add_Edge(int x, int y) {
Next[++tot] = Head[x], Head[x] = tot, To[tot] = y;
Next[++tot] = Head[y], Head[y] = tot, To[tot] = x;
}
bool dfs(int x) {
for (int i = Head[x]; i; i = Next[i]) {
int v = To[i];
if (!vis[v]) {
vis[v] = 1;
if (match[v] == -1 || dfs(match[v])) {
match[v] = x;
return true;
}
}
}
return false;
}
int Maxmatch() {
int sum = 0;
memset(match, -1, sizeof(match));
for (int i = 1; i <= n; i++) {
memset(vis, 0, sizeof(vis));
if (dfs(i)) sum++;
}
return sum;
}
int main() {
while (cin >> n >> m) {
tot = 1;
memset(Head, 0, sizeof(Head));
memset(color, -1, sizeof(color));
bool flag = true;
int x, y;
for (int i = 1; i <= m; i++) {
cin >> x >> y;
Add_Edge(x, y);
}
for (int i = 1; i <= n; i++) {//染色法判断是否是二分图
if (color[i] == -1) color[i] = 0;
for (int j = Head[i]; j; j = Next[j]) {
int v = To[j];
if (color[v] == -1) color[v] = abs(color[i] - 1);
else if (color[v] == color[i]) flag = false;
else continue;
}
}
if (!flag) {
printf("No\n");
continue;
}
int ans = Maxmatch();
cout << ans / 2 << "\n";
}
return 0;
}