一般图最大匹配+输出方案
1 #include <bits/stdc++.h> 2 using namespace std; 3 namespace edmond { 4 const int LEN = 4e4 + 5; 5 int n, m, ans, tot, qh, qt, Time; 6 int head[LEN], pre[LEN], fa[LEN], flag[LEN], nxt[LEN], q[LEN], vis[LEN]; 7 struct edge { 8 int vet, next, len; 9 } E[LEN * 2]; 10 void add(int u, int v) { 11 E[++tot] = (edge){v, head[u]}; 12 head[u] = tot; 13 } 14 int getf(int x) { 15 if (fa[x] != x) fa[x] = getf(fa[x]); 16 return fa[x]; 17 } 18 int lca(int x, int y) { 19 ++Time; 20 x = getf(x), y = getf(y); 21 for (;;swap(x, y)) { 22 if (x) { 23 if (flag[x] == Time) return x; 24 flag[x] = Time; 25 x = getf(pre[nxt[x]]); 26 } 27 } 28 return x; 29 } 30 void blossom(int x, int y, int z) { 31 while (getf(x) != z) { 32 pre[x] = y; 33 y = nxt[x]; 34 if (vis[y] == 1) { 35 q[++qt] = y; 36 vis[y] = 0; 37 } 38 if (fa[x] == x) fa[x] = z; 39 if (fa[y] == y) fa[y] = z; 40 x = pre[y]; 41 } 42 } 43 int match(int s) { 44 for (int i = 0; i <= n; i++) { 45 fa[i] = i; 46 vis[i] = -1; 47 } 48 qh = qt = 0; 49 q[++qt] = s; 50 vis[s] = 0; 51 while (qh < qt) { 52 int u = q[++qh]; 53 for (int e = head[u]; e != -1; e = E[e].next) { 54 int v = E[e].vet; 55 if (vis[v] == -1) { 56 pre[v] = u; 57 vis[v] = 1; 58 if (!nxt[v]) { 59 for (int x = v, y = u, last; y; x = last, y = pre[x]) { 60 last = nxt[y]; 61 nxt[y] = x; 62 nxt[x] = y; 63 64 } 65 return 1; 66 } 67 q[++qt] = nxt[v]; 68 vis[nxt[v]] = 0; 69 } else if (!vis[v] && getf(v) != getf(u)) { 70 int w = lca(v, u); 71 blossom(u, v, w); 72 blossom(v, u, w); 73 } 74 } 75 } 76 return 0; 77 } 78 void init() { 79 Time = 0; 80 tot = -1; 81 for (int i = 1; i <= n; i++) { 82 head[i] = -1; 83 flag[i] = nxt[i] = pre[i] = 0; 84 } 85 } 86 } 87 using namespace edmond; 88 int main() { 89 scanf("%d %d", &n, &m); 90 init(); 91 for (int i = 1; i <= m; i++) { 92 int x, y; 93 scanf("%d %d", &x, &y); 94 add(x, y); 95 add(y, x); 96 } 97 for (int i = n; i >= 1; i--) { 98 if (!nxt[i]) ans += match(i); 99 } 100 printf("%d ", ans); 101 for (int i = 1; i < n; i++) printf("%d ", nxt[i]); 102 printf("%d ", nxt[n]); 103 return 0; 104 }