支配树模板
只是一个板子,甚至没怎么写注释
#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;
}