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

HDU.4694.Important Sisters(支配树)

时间:2018-12-15 15:54:50      阅读:298      评论:0      收藏:0      [点我收藏+]

标签:arc   code   uri   cst   .net   php   script   tor   tps   

HDU

\(Description\)

给定一张简单有向图,起点为\(n\)。对每个点求其支配点的编号和。
\(n\leq 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\n",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(支配树)

标签:arc   code   uri   cst   .net   php   script   tor   tps   

原文地址:https://www.cnblogs.com/SovietPower/p/10123414.html

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