http://www.cnblogs.com/y-clever/p/8084738.html
带花树算法
#include <bits/stdc++.h>
using namespace std;
const int maxn = 222 + 5;
deque<int> Q;
bool g[maxn][maxn], inque[maxn], inblossom[maxn], inpath[maxn];
int match[maxn], pre[maxn], base[maxn];
int findAncestor(int u, int v) {
memset(inpath, false, sizeof(inpath));
while(true) {
u = base[u];
inpath[u] = true;
if(match[u] == -1) break;
u = pre[match[u]];
}
while(true) {
v = base[v];
if(inpath[v]) return v;
v = pre[match[v]];
}
}
void reset(int u, int anc) {
while(u != anc) {
int v = match[u];
inblossom[base[u]] = 1;
inblossom[base[v]] = 1;
v = pre[v];
if(base[v] != anc) pre[v] = match[u];
u = v;
}
}
void contract(int u, int v, int n) {
int anc = findAncestor(u, v);
memset(inblossom, 0, sizeof(inblossom));
reset(u, anc);
reset(v, anc);
if(base[u] != anc) pre[u] = v;
if(base[v] != anc) pre[v] = u;
for(int i = 1; i <= n; ++i)
if(inblossom[base[i]]) {
base[i] = anc;
if(!inque[i]) {
Q.push_back(i);
inque[i] = 1;
}
}
}
bool bfs(int S, int n) {
for(int i = 0; i <= n; ++i) pre[i] = -1, inque[i] = 0, base[i] = i;
Q.clear();
Q.push_back(S);
inque[S] = 1;
while(!Q.empty()) {
int u = Q.front();
Q.pop_front();
for(int v = 1; v <= n; ++v) {
if(g[u][v] && base[v] != base[u] && match[u] != v) {
if(v == S || (match[v] != -1 && pre[match[v]] != -1)) contract(u, v, n);
else if(pre[v] == -1) {
pre[v] = u;
if(match[v] != -1) Q.push_back(match[v]), inque[match[v]] = 1;
else {
u = v;
while(u != -1) {00000
v = pre[u];
int w = match[v];
match[u] = v;
match[v] = u;
u = w;
}
return true;
}
}
}
}
}
return false;
}
int solve(int n) {
memset(match, -1, sizeof(match));
int ans = 0;
for(int i = 1; i <= n; ++i)
if(match[i] == -1 && bfs(i, n))
ans++;
return ans;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
int n;
cin >> n;
int u, v;
while(cin >> u >> v) {
g[u][v] = g[v][u] = 1;
}
int ans = solve(n);
cout << ans * 2 << endl;
for(int i = 1; i <= n; ++i) {
if(match[i] == -1) continue;
cout << i << " " << match[i] << endl;
match[match[i]] = -1;
match[i] = -1;
}
}