http://acm.hdu.edu.cn/showproblem.php?pid=2444
题意:给出边,判断这个是否是一个二分图,并求最大匹配。
思路:先染色法求出是否是一个二分图,然后再匈牙利求出最大匹配。注意输出是“No"而不是”NO“!!!
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <string>
#include <iostream>
#include <stack>
#include <map>
#include <queue>
using namespace std;
#define N 100010
#define INF 0x3f3f3f3f
struct node
{
int nxt, v;
}edge[*];
int head[], tot;
int col[];
bool vis[];
int match[]; void add(int u, int v)
{
edge[tot].v = v; edge[tot].nxt = head[u]; head[u] = tot++;
} bool check(int u,int c)
{
col[u] = c;
for(int i = head[u]; ~i; i = edge[i].nxt) {
int v = edge[i].v;
if(col[v] == c) return false;
if(col[v] == && !check(v, -c)) return false;
}
return true;
} bool dfs(int u)
{
for(int i = head[u]; ~i; i = edge[i].nxt) {
int v = edge[i].v;
if(!vis[v]) {
vis[v] = ;
if(match[v] == - || dfs(match[v])) {
match[v] = u;
return true;
}
}
}
return false;
} int main()
{
int n, m;
while(~scanf("%d%d", &n, &m)) {
memset(match, -, sizeof(match));
memset(head, -, sizeof(head));
memset(col, , sizeof(col));
tot = ;
for(int i = ; i < m; i++) {
int u, v;
scanf("%d%d", &u, &v);
add(u, v); add(v, u);
}
bool f = ;
for(int i = ; i <= n; i++) {
if(col[i] == ) {
if(!check(i, )) {
f = ;
puts("No");
break;
}
}
}
if(!f) continue;
int sum = ;
for(int i = ; i <= n; i++) {
memset(vis, , sizeof(vis));
sum += dfs(i);
}
printf("%d\n", sum / );
}
return ;
}