码迷,mamicode.com
首页 > 其他好文 > 详细

luogu P6113 【模板】一般图最大匹配 带花树

时间:2020-06-03 00:40:13      阅读:54      评论:0      收藏:0      [点我收藏+]

标签:size   ems   continue   最大匹配   oid   style   etc   amp   als   

#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\n",ans);
    for(int i=1; i<=n; ++i)
        printf("%d ",lk[i]);
    return 0*puts("");
}

 

luogu P6113 【模板】一般图最大匹配 带花树

标签:size   ems   continue   最大匹配   oid   style   etc   amp   als   

原文地址:https://www.cnblogs.com/QingyuYYYYY/p/13034747.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!