支配树模板

支配树模板

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

#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;
}
原文地址:https://www.cnblogs.com/butterflydew/p/10274209.html