P6113 【模板】一般图最大匹配
匈牙利算法最大的问题在于无法处理带奇环的图,如果存在奇环,那么程序会T掉
带花树算法就是用于处理奇环的问题
#include <bits/stdc++.h> #define inf 0x7fffffff #define ll long long //#define int long long //#define double long double #define re register int #define void inline void #define eps 1e-5 //#define mod 1e9+7 #define ls(p) p<<1 #define rs(p) p<<1|1 //#define ls(p) e[p].l //#define rs(p) e[p].r //#define pi acos(-1.0) #define pb push_back #define P pair < int , int > #define mk make_pair #define fi first #define se second using namespace std; const int mod=998244353; const int N=1e5+5;//?????????? 4e8. int n,m; namespace GP { queue < int > q; struct node { int ver,next; }e[N]; int tot,head[N]; int num=0; int fa[N],v[N],pre[N],match[N],dfn[N]; void add(int x,int y) { e[++tot].ver=y; e[tot].next=head[x]; head[x]=tot; } void addedge(int x,int y) { add(x,y);add(y,x); } int get(int x) { return fa[x]==x?x:fa[x]=get(fa[x]); } int lca(int x,int y) { num++; x=get(x),y=get(y); while(dfn[x]!=num) { dfn[x]=num; x=get(pre[match[x]]); if(y) swap(x,y); } return x; } void blossom(int x,int y,int z) { while(get(x)!=z) { pre[x]=y;y=match[x]; if(v[y]==2) { v[y]=1; q.push(y); } if(x==get(x)) fa[x]=z; if(y==get(y)) fa[y]=z; x=pre[y]; } } bool bfs(int s) { while(q.size()) q.pop(); for(re i=1;i<=n;i++) fa[i]=i,v[i]=pre[i]=0; v[s]=1,q.push(s); while(q.size()) { int x=q.front();q.pop(); for(re i=head[x];i;i=e[i].next) { int y=e[i].ver; if(v[y]==2||get(x)==get(y)) continue; if(!v[y]) { v[y]=2;pre[y]=x; if(!match[y]) { for(re u=y,lst;u;u=lst) { lst=match[pre[u]]; match[u]=pre[u]; match[pre[u]]=u; } return 1; } v[match[y]]=1; q.push(match[y]); } else { int w=lca(x,y); blossom(x,y,w);blossom(y,x,w); } } } return 0; } } void solve() { cin>>n>>m; for(re i=1;i<=m;i++) { int x,y; scanf("%d%d",&x,&y); GP::addedge(x,y); } int p=0; for(re i=1;i<=n;i++) if(!GP::match[i]) p+=GP::bfs(i); printf("%d\n",p); for(re i=1;i<=n;i++) printf("%d ",GP::match[i]); } signed main() { // freopen("P1505_1.txt", "r", stdin); // freopen("Aout.txt", "w", stdout); int T=1; // cin>>T; for(int index=1;index<=T;index++) { // printf("Case #%lld: ",index); solve(); // puts(""); } return 0; } /* 10 5 hbtngdflmj 1 10 1 2 9 0 3 8 1 4 7 0 5 6 1 */