求一般图的最大匹配。
带花树模板题。
模板链接:https://blog.csdn.net/Frods/article/details/54564401
AC代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdlib>
#include<utility>
#include<algorithm>
#include<utility>
#include<queue>
#include<vector>
#include<set>
#include<stack>
#include<cmath>
#include<map>
#include<ctime>
#define P pair<int,int>
#define ll long long
#define ull unsigned long long
#define lson id*2,l,mid
#define rson id*2+1,mid+1,r
#define ls id*2
#define rs id*2+1
#define Mod(a,b) a<b?a:a%b+b
using namespace std;
const ll M = 1e9 + 7;
const ll INF = 1e9;
const int N = 510;
const double e = 10e-6;
int n, m;
struct blossemtree {
vector<int>g[N];queue<int>q;
int fa[N], type[N], link[N], Next[N], vis[N];
int find(int x) {
if (x == fa[x]) return x;
return fa[x] = find(fa[x]);
}
void add(int u, int v) {
g[u].push_back(v);
}
void combine(int x, int lca) {
while (x != lca) {
int u = link[x], v = Next[u];
if (find(v) != lca) Next[v] = u;
if (type[u] == 1) type[u] = 2, q.push(u);
fa[find(x)] = find(u);fa[find(u)] = find(v);
x = v;
}
}
void contrack(int x, int y) {
int lca = x;
memset(vis, 0, sizeof(vis));
for (int i = x; i; i = Next[link[i]]) {
i = find(i);
vis[i] = 1;
}
for (int i = y; i; i = Next[link[i]]) {
i = find(i);
if (vis[i]) {
lca = i;
break;
}
}
if (lca != find(x)) Next[x] = y;
if (lca != find(y)) Next[y] = x;
combine(x, lca);combine(y, lca);
}
void bfs(int S) {
memset(type, 0, sizeof(type));
memset(Next, 0, sizeof(Next));
for (int i = 1; i <= n; i++)
fa[i] = i;
while (!q.empty())
q.pop();
q.push(S); type[S] = 2;
while (!q.empty()) {
int x = q.front();q.pop();
for (int i = 0; i < g[x].size(); i++) {
int y = g[x][i];
if (find(x) == find(y) || link[x] == y || type[y] == 1) continue;
if (type[y] == 2)
contrack(x, y);
else if (link[y]) {
Next[y] = x;
type[y] = 1;
type[link[y]] = 2;
q.push(link[y]);
}
else {
Next[y] = x;
int pos = y, u = Next[pos], v = link[u];
while (pos) {
link[pos] = u; link[u] = pos;
pos = v;
u = Next[pos]; v = link[u];
}
return;
}
}
}
}
int maxmatch() {
for (int i = 1; i <= n; i++)
if (!link[i]) bfs(i);
int ans = 0;
for (int i = 1; i <= n; i++)
if (link[i]) ans++;
return ans / 2;
}
void init() {
for (int i = 1; i <= n; i++) g[i].clear();
memset(link, 0, sizeof(link));
}
}tree;
int main() {
int u, v;
while (~scanf("%d%d", &n, &m)) {
tree.init();
while (m--) {
scanf("%d%d", &u, &v);
tree.add(u, v); tree.add(v, u);
}
printf("%d\n", tree.maxmatch());
for (int i = 1; i <= n; i++)
printf("%d ", tree.link[i]);
printf("\n");
}
return 0;
}