zoukankan      html  css  js  c++  java
  • 图论:带花树算法-一般图最大匹配

    一般图匹配就是给一般图像二分图那样做最大匹配

    问你最大能匹配多少对,带花树算法的过程这里不再描述

    直接上模板

     1 //It is made by ljh2000
     2 #include <iostream>
     3 #include <cstdlib>
     4 #include <cstring>
     5 #include <cstdio>
     6 #include <cmath>
     7 #include <algorithm>
     8 using namespace std;
     9 typedef long long LL;
    10 const int MAXN = 520;
    11 const int MAXM = 250011;
    12 const int MAXL = 10011;
    13 int n,m,ecnt,first[MAXN],next[MAXM],to[MAXM],father[MAXN],Tim;
    14 int dui[MAXL],head,tail,id[MAXN],pre[MAXN],match[MAXN],ans,vis[MAXN];
    15 inline int find(int x){ if(father[x]!=x) father[x]=find(father[x]); return father[x]; }
    16 inline int getint(){
    17     int w=0,q=0; char c=getchar(); while((c<'0'||c>'9') && c!='-') c=getchar();
    18     if(c=='-') q=1,c=getchar(); while (c>='0'&&c<='9') w=w*10+c-'0',c=getchar(); return q?-w:w;
    19 }
    20  
    21 inline int lca(int x,int y){
    22     Tim++;
    23     while(vis[x]!=Tim) {
    24         if(x) {
    25             x=find(x);
    26             if(vis[x]==Tim) return x;
    27             vis[x]=Tim;
    28             if(match[x]!=0) x=find(pre[match[x]]);
    29             else x=0;
    30         }
    31         swap(x,y);
    32     }
    33     return x;
    34 }
    35  
    36 inline void change(int x,int y,int k){//把奇环上的点缩成一个点,并且把原来是奇点的点变成偶点,加入队列
    37     while(find(x)!=k) {
    38         pre[x]=y; int z=match[x];
    39         if(id[z]==1) { id[z]=0; dui[++tail]=z; }
    40         if(find(z)==z) father[z]=k;
    41         if(find(x)==x) father[x]=k;
    42         y=z; x=pre[y];
    43     }
    44 }
    45  
    46 inline bool bfs(int ini){
    47     for(int i=1;i<=n;i++) id[i]=-1,father[i]=i;
    48     head=tail=0; dui[++tail]=ini; id[ini]=0; int u;
    49     while(head<tail) {
    50         u=dui[++head];
    51         for(int i=first[u];i;i=next[i]) {
    52             int v=to[i];
    53             if(id[v]==-1) {
    54                 pre[v]=u; id[v]=1;
    55                 if(!match[v]) {
    56                     int last,t,now=v;
    57                     while(now!=0) {
    58                         t=pre[now]; last=match[t];
    59                         match[t]=now; match[now]=t;
    60                         now=last;
    61                     }
    62                     return true;
    63                 }
    64                 id[match[v]]=0; dui[++tail]=match[v];
    65             }
    66             else if(id[v]==0&&find(u)!=find(v)){ //出现奇环且不是在同一个环中
    67                 int g=lca(u,v);
    68                 change(u,v,g);
    69                 change(v,u,g);
    70             }
    71         }
    72     }
    73     return false;
    74 }
    75  
    76 inline void work(){
    77     n=getint(); m=getint(); int x,y;
    78     for(int i=1;i<=m;i++) {
    79         x=getint(); y=getint();
    80         next[++ecnt]=first[x]; first[x]=ecnt; to[ecnt]=y;
    81         next[++ecnt]=first[y]; first[y]=ecnt; to[ecnt]=x;
    82     }
    83     for(int i=1;i<=n;i++) if(!match[i]&&bfs(i)) ans++;
    84     printf("%d
    ",ans);
    85     for(int i=1;i<=n;i++) printf("%d ",match[i]);
    86 }
    87  
    88 int main()
    89 {
    90     work();
    91     return 0;
    92 }
  • 相关阅读:
    centos mongo数据库搭建
    闪屏页白屏或者显示旧图
    在Sqlserver下巧用行列转换日期的数据统计
    读 《.Net 之美》解析.Net Remoting (应用程序域)-- Part.1
    MVC的自定义动作过滤器(一)
    【算法】快排
    【编程范式】C语言1
    排序
    日志记录类
    邮箱发送类
  • 原文地址:https://www.cnblogs.com/aininot260/p/9623690.html
Copyright © 2011-2022 走看看