一般图匹配

一般图最大匹配+输出方案

  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\n", ans);
101     for (int i = 1; i < n; i++) printf("%d ", nxt[i]);
102     printf("%d\n", nxt[n]);
103     return 0;
104 }
带花树

猜你喜欢

转载自www.cnblogs.com/NineSwords/p/9469936.html