带花树算法解决一般图最大匹配

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

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

直接上模板

 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\n",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 }

猜你喜欢

转载自www.cnblogs.com/aininot260/p/9623690.html