zoukankan      html  css  js  c++  java
  • (留坑以后再看)一般图'最大匹配' 带花树 算法

    // 看了大半天也没看懂 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
    ", solve());
    102         for(int i = 1; i <= n; ++i) {
    103             if(i != 1) printf(" ");
    104             printf("%d", love[i]);
    105         }
    106         printf("
    ");
    107     }
    108     return 0;
    109 }
  • 相关阅读:
    Kotlin 学习 (一)
    Spring Boot 学习(一)
    三大特性之继承
    OC中的点语法
    getter和setter
    三大特性之封装
    匿名对象
    对象作为返回值
    对象作为参数的连续传递
    对象作为参数传递
  • 原文地址:https://www.cnblogs.com/pupil-xj/p/11808200.html
Copyright © 2011-2022 走看看