(留坑以后再看)一般图'最大匹配' 带花树 算法

// 看了大半天也没看懂 8h左右 头看疼了。

// 直接贴博客:

https://www.cnblogs.com/BAJimH/p/10569418.html

http://www.csie.ntnu.edu.tw/~u91029/Matching.html

https://blog.csdn.net/qq_30974369/article/details/79819292

模板

UOJ 79

  1 #include<cstdio>
  2 #include<queue>
  3 using namespace std;
  4 const int MAXN = 500+5;
  5 const int MAXE = 124750*2+5;
  6 
  7 int num;
  8 int head[MAXN];
  9 struct node {
 10     int v, next;
 11 } edge[MAXE];
 12 
 13 inline void add(int x, int y) {
 14     edge[num] = (node){y, head[x]};
 15     head[x] = num++;
 16 }
 17 
 18 int n, m;
 19 int love[MAXN];
 20 int vis[MAXN], fa[MAXN], pre[MAXN];
 21 int tim, dfn[MAXN];
 22 queue<int> q;
 23 
 24 inline int find(int x) { return x == fa[x] ? x : fa[x] = find(fa[x]); }
 25 
 26 inline int LCA(int u, int v) {
 27     ++tim; u = find(u), v = find(v);
 28     while(dfn[u] != tim) {
 29         dfn[u] = tim;
 30         u = find(pre[love[u]]);
 31         if(v) swap(u, v);
 32     }
 33     return u;
 34 }
 35 
 36 inline void Blossom(int x, int y, int lca) {
 37     while(find(x) != lca) {
 38         pre[x] = y, y = love[x];
 39         if(vis[y] == 2) vis[y] = 1, q.push(y);
 40         if(find(x) == x) fa[x] = lca;
 41         if(find(y) == y) fa[y] = lca;
 42         x = pre[y];
 43     }
 44 }
 45 
 46 bool Aug(int s) {
 47     for(int i = 1; i <= n; ++i) fa[i] = i, vis[i] = pre[i] = 0;
 48     while(!q.empty()) q.pop();    
 49     q.push(s);
 50     vis[s] = 1;
 51     while(!q.empty()) {
 52         int u = q.front();
 53         q.pop();
 54         for(int i = head[u]; i != -1; i = edge[i].next) {
 55             int v = edge[i].v;
 56             if(find(u) == find(v) || vis[v] == 2) continue;
 57             if(!vis[v]) {
 58                 vis[v] = 2;
 59                 pre[v] = u;
 60                 if(!love[v]) {
 61                     for(int x = v, lst; x; x = lst) {
 62                         lst = love[pre[x]];
 63                         love[x] = pre[x];
 64                         love[pre[x]] = x;
 65                     }
 66                     return true;
 67                 }
 68                 //else
 69                 vis[love[v]] = 1;/
 70                 q.push(love[v]);
 71             }
 72             else {
 73                 int lca = LCA(u, v);
 74                 Blossom(u, v, lca);
 75                 Blossom(v, u, lca);
 76             }
 77         }
 78     }
 79     return false;
 80 }
 81 
 82 int solve() {
 83     int ans = 0;
 84     tim = 0;
 85     for(int i = 1; i <= n; ++i) love[i] = 0;
 86     for(int i = 1; i <= n; ++i) {
 87         if(!love[i] && Aug(i)) ++ans;
 88     }
 89     return ans;
 90 }
 91 
 92 int main() {
 93     while(scanf("%d%d", &n, &m) == 2) {
 94         int num = 0;
 95         for(int i = 1; i <= n; ++i) head[i] = -1;
 96         int x, y;
 97         for(int i = 0; i != m; ++i) {
 98             scanf("%d%d", &x, &y);
 99             add(x, y); add(y, x);
100         }
101         printf("%d\n", solve());
102         for(int i = 1; i <= n; ++i) {
103             if(i != 1) printf(" ");
104             printf("%d", love[i]);
105         }
106         printf("\n");
107     }
108     return 0;
109 }

 

posted @ 2019-11-06 19:51  pupil337  阅读(178)  评论(0编辑  收藏  举报