支配树模板

支配树模板

只是一个板子,甚至没怎么写注释

#include <cstdio>
#include <vector>
const int N=2e5+10;
std::vector <int> dew[N],bee[N],yuyuyu[N];
int dfn[N],ha[N],fa[N],dfsclock,n,m;
void dfs(int now)
{
    ha[dfn[now]=++dfsclock]=now;
    for(int v,i=0;i<dew[now].size();i++)
        if(!dfn[v=dew[now][i]])
            fa[v]=now,dfs(v);
}
int siz[N],semi[N],idom[N];
void dfs0(int now)
{
    siz[now]=1;
    for(int v,i=0;i<dew[now].size();i++)
        dfs0(v=dew[now][i]),siz[now]+=siz[v];
}
int f[N],mi[N];
int Find(int now)
{
    if(f[now]==now) return now;
    int par=f[now];f[now]=Find(now);
    if(dfn[semi[mi[now]]]>dfn[semi[mi[par]]]) mi[now]=mi[par];
    return f[now];
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int u,v,i=1;i<=m;i++)
    {
        scanf("%d%d",&u,&v);
        dew[u].push_back(v);
        bee[v].push_back(u);
    }
    dfs(1);
    for(int i=1;i<=n;i++) mi[i]=semi[i]=f[i]=i,dew[i].clear();
    for(int k=n;k>1;k--)
    {
        int now=ha[k];
        for(int v,i=0;i<bee[now].size();i++)
        {
            v=bee[now][i];
            Find(v);//不判没影响
            semi[now]=dfn[semi[now]]<dfn[semi[mi[v]]]?semi[now]:semi[mi[v]];
        }
        yuyuyu[semi[now]].push_back(now);
        f[now]=fa[now],now=fa[now];
        for(int v,i=yuyuyu[now].size()-1;~i;i--)
        {
            Find(v=yuyuyu[now][i]);
            if(now==semi[mi[v]]) idom[v]=now;
            else idom[v]=mi[v];//等会从上面再更新
        }
        yuyuyu[now].clear();
    }
    for(int now,i=2;i<=n;i++)
    {
        now=ha[i];
        if(idom[now]!=semi[now]) idom[now]=idom[idom[now]];
        dew[idom[now]].push_back(now);
    }
    dfs0(1);
    for(int i=1;i<=n;i++) printf("%d ",siz[i]);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/ppprseter/p/10274209.html