luogu P6113 模板一般图最大匹配 带花树
Posted qingyuyyyyy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了luogu P6113 模板一般图最大匹配 带花树相关的知识,希望对你有一定的参考价值。
#include<bits/stdc++.h> #pragma GCC optimize(3) using namespace std; const int N=1009,M=100009; int n,m,ans,ord,q[M],pre[N]; int ql,qr,dfn[N],lk[N]; int cl[N],g[N]; int e[M],ne[M],h[M],idx; void rd(int&x) //貌似加了快读瞬间加速近30ms,因此还是加了。 { char c=getchar(); x=0; while(c>57||c<48)c=getchar(); while(c>47&&c<58) x+=(x<<3)+x+c-48,c=getchar(); } int find(int x) { return g[x]==x?x:g[x]=find(g[x]); } void add(int a,int b) { e[idx]=b; ne[idx]=h[a]; h[a]=idx++; } int lca(int x,int y) { for(++ord; x=find(x); swap(x,y)) if(dfn[x]==ord)return x;//奇环编号相同,说明找到了。 else dfn[x]=ord,x=pre[lk[x]]; } void flw(int x,int y,int p) //开花。 { while(find(x)!=p) { pre[x]=y,y=lk[x]; if(cl[y]==2)cl[y]=1,q[++qr]=y; g[x]=p,g[y]=p,x=pre[y]; } } bool dfs(int x) { for(int i=1; i<=n; ++i)g[i]=i; memset(cl,0,sizeof(cl)); memset(pre,0,sizeof(pre)); cl[q[ql=qr=1]=x]=1;//颜色为黑。 for(int x=q[ql]; ql<=qr; x=q[++ql]) for(int i=h[x],v,z; ~i; i=ne[i]) { if(cl[v=e[i]]==2)continue; if(find(v)==find(x))continue; if(cl[v]==1) z=lca(x,v),flw(x,v,z),flw(v,x,z); else if(!cl[v]) { cl[v]=2,pre[v]=x; if(!lk[v]) { for(int u=v,lst,y; u; u=lst) lst=lk[y=pre[u]],lk[u]=y,lk[y]=u;//找到增广路了,一路取反。 return true;//答案+1。 } cl[lk[v]]=1,q[++qr]=lk[v];//匹配它的点一定是黑点。 } } return false; } int main() { memset(h,-1,sizeof h); scanf("%d%d",&n,&m); for(int u,v; m; --m) rd(u),rd(v),add(u,v),add(v,u); for(int i=1; i<=n; ++i) ans+=(!lk[i]&&dfs(i)); printf("%d ",ans); for(int i=1; i<=n; ++i) printf("%d ",lk[i]); return 0*puts(""); }
以上是关于luogu P6113 模板一般图最大匹配 带花树的主要内容,如果未能解决你的问题,请参考以下文章