HDU.4694.Important Sisters(支配树)

Posted sovietpower

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU.4694.Important Sisters(支配树)相关的知识,希望对你有一定的参考价值。

HDU

(Description)

给定一张简单有向图,起点为(n)。对每个点求其支配点的编号和。
(nleq 50000)

(Solution)

支配树。

还是有点小懵逼。
不管了,说不定会讲,反正以后再说。

https://blog.csdn.net/litble/article/details/83019578
有图的:https://blog.csdn.net/VioletSu/article/details/81041954
有题的:https://blog.csdn.net/L_0_Forever_LF/article/details/79386508
有怎么卡纯路径压缩并查集的:https://www.cnblogs.com/meowww/archive/2017/02/27/6475952.html

记几个名词:
(Lengauer Tarjan)算法。
半支配点((semi-dominator)),记作(semi(x))
最近支配点((immediate dominator)),记作(idom(x))


想不到我竟然也有把if(x==y)写成if(x=y)而且还调半天的时候...

//1107MS    8292K
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
#define gc() getchar()
typedef long long LL;
const int N=50005,M=1e5+5;

int Index,dfn[N],ref[N],F[N],fa[N],mn[N],semi[N],idom[N],Ans[N];
struct Graph
{
    int Enum,H[N],nxt[M],to[M];
    inline void Clear(int n)
    {
        Enum=0, memset(H,0,n+1<<2);
    }
    inline void AE(int u,int v)
    {
        to[++Enum]=v, nxt[Enum]=H[u], H[u]=Enum;
    }
}G,RG,SG,T;

inline int read()
{
    int now=0;register char c=gc();
    for(;!isdigit(c);c=gc());
    for(;isdigit(c);now=now*10+c-'0',c=gc());
    return now;
}
void DFS0(int x)
{
    ref[dfn[x]=++Index]=x;
    for(int i=G.H[x],v; i; i=G.nxt[i])
        if(!dfn[v=G.to[i]]) fa[v]=x, DFS0(v);
}
int Find(int x)
{
    if(x==F[x]) return x;
    int tmp=F[x];
    F[x]=Find(F[x]);
    if(dfn[semi[mn[tmp]]]<dfn[semi[mn[x]]]) mn[x]=mn[tmp];
    return F[x];
}
void DFS(int x,int s)
{
    Ans[x]=s+=x;
    for(int i=T.H[x]; i; i=T.nxt[i]) DFS(T.to[i],s);
}
void Solve(int n)
{
    for(int k=n; k>1; --k)
    {
        int x=ref[k],t=n;//求半支配点 
        for(int i=RG.H[x],v; i; i=RG.nxt[i])
            if(dfn[v=RG.to[i]])
                if(dfn[v]<dfn[x]) t=std::min(t,dfn[v]);
                else Find(v), t=std::min(t,dfn[semi[mn[v]]]);
        F[x]=fa[x], SG.AE(semi[x]=ref[t],x);

        x=ref[k-1];//从半支配点到支配点 
        for(int i=SG.H[x],v; i; i=SG.nxt[i])
        {
            Find(v=SG.to[i]);
            if(semi[v]==semi[mn[v]]) idom[v]=semi[v];
            else idom[v]=mn[v];//idom[mn[v]]此时可能并未找到 
        }
    }
    for(int k=2,x; k<=n; ++k)
    {
        x=ref[k];
        if(idom[x]!=semi[x]) idom[x]=idom[idom[x]];
        T.AE(idom[x],x);
    }
    DFS(n,0);
    for(int i=1; i<n; printf("%d ",Ans[i++]));
    printf("%d
",Ans[n]), memset(Ans,0,n+1<<2);
}

int main()
{
    int n,m;
    while(~scanf("%d%d",&n,&m))
    {
        for(int i=1,u,v; i<=m; ++i) u=read(),v=read(),G.AE(u,v),RG.AE(v,u);
        for(int i=1; i<=n; ++i) F[i]=semi[i]=mn[i]=i;
        Index=0, DFS0(n), Solve(n);
        G.Clear(n), RG.Clear(n), SG.Clear(n), T.Clear(n);
        memset(dfn,0,n+1<<2), memset(idom,0,n+1<<2), memset(ref,0,n+1<<2);//, memset(fa,0,n+1<<2);//不都清空会RE啊== 
    }
    return 0;
}

以上是关于HDU.4694.Important Sisters(支配树)的主要内容,如果未能解决你的问题,请参考以下文章

尝试通过 ASP.NET 中的命令文本在 SQL Server 2014 中插入“Rahul's Sister”时出错 [重复]

与同一模型相关联

摘人生苦短, 每日python

UPC2018组队训练赛第三场

python 之 BeautifulSoup标签查找与信息提取

My situation