• [hdu4694]Important Sisters


    来自FallDream的博客,未经允许,请勿转载,谢谢。


    给定一张图,求每个点到第n个点必须经过的点的编号之和。n<=50000

    一道支配树裸题

    然后统计答案的时候可以正着推,ans[i]=ans[idom[i]]+i

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define MN 50000
    #define ll long long
    using namespace std;
    inline int read()
    {
        int x = 0 , f = 1; char ch = getchar();
        while(ch < '0' || ch > '9'){ if(ch == '-') f = -1;  ch = getchar();}
        while(ch >= '0' && ch <= '9'){x = x * 10 + ch - '0';ch = getchar();}
        return x * f;
    }
    ll val[MN+5];
    int n,m,cnt,tot=0,mark[MN+5],dn,head[MN+5],Fa[MN+5],fa[MN+5],top[MN+5],back[MN+5],Best[MN+5],dfn[MN+5],id[MN+5],s[MN+5],d[MN+5];
    struct edge{int to,next;}e[MN*100];
    inline void ins(int*H,int f,int t){e[++cnt]=(edge){t,H[f]};H[f]=cnt;}
    
    void Pre(int x)
    {
        id[dfn[x]=++dn]=x;
        for(int    i=head[x];i;i=e[i].next)
            if(!dfn[e[i].to]) Fa[e[i].to]=x,Pre(e[i].to);
    }
    inline bool P(int x,int y){return dfn[x]>dfn[y];}
    inline int Up(int x)
    {
        if(fa[x]==x) return x;
        int y=Up(fa[x]);
        if(P(s[Best[x]],s[Best[fa[x]]])) Best[x]=Best[fa[x]];
        return fa[x]=y;
    }
    
    inline void Tarjan()
    {
        for(int i=dn;i>1;--i)
        {
            int u=id[i];
            for(int j=back[u];j;j=e[j].next)
                if(dfn[e[j].to])
                    Up(e[j].to),P(s[u],s[Best[e[j].to]])?s[u]=s[Best[e[j].to]]:0;
            ins(top,s[u],u);fa[u]=Fa[u];u=Fa[u];
            for(int j=top[u];j;j=e[j].next)
            {
                Up(e[j].to);
                if(s[Best[e[j].to]]==s[u]) d[e[j].to]=u;
                else d[e[j].to]=Best[e[j].to];
            }
        }
        for(int i=2;i<=dn;++i) if(d[id[i]]!=s[id[i]]) d[id[i]]=d[d[id[i]]];
    }
    
    int main()
    {
        while(scanf("%d%d",&n,&m)!=EOF)
        {
            cnt=dn=0;++tot;
            memset(head,0,sizeof(int)*(n+2));
            memset(back,0,sizeof(int)*(n+2));
            memset(top,0,sizeof(int)*(n+2));
            memset(val,0,sizeof(ll)*(n+2));
            memset(dfn,0,sizeof(int)*(n+2));
            memset(d,0,sizeof(int)*(n+2));
            for(int i=1;i<=m;++i)
            {
                int u=read(),v=read();
                ins(head,u,v);
                ins(back,v,u);    
            }
            for(int i=1;i<=n;++i) Best[i]=s[i]=fa[i]=i;    
            Pre(n);Tarjan();
            for(int i=1;i<=dn;++i) val[id[i]]=val[d[id[i]]]+id[i];
            for(int i=1;i<=n;++i) printf("%I64d%c",dfn[i]?val[i]:0,i==n?'
    ':' ');
        }
        return 0;
    }
  • 相关阅读:
    Python自动化之面向对象进阶
    Python自动化之pickle和面向对象初级篇
    Python自动化之常用模块
    剑指offer 顺时针打印矩阵
    剑指 offer 树的子结构
    剑指offer 合并两个排序的链表
    剑指offer 调整数组顺序使奇数位于偶数前面
    剑指offer 数值的整数次方
    变态跳台阶
    剑指offer 重建二叉树
  • 原文地址:https://www.cnblogs.com/FallDream/p/hdu4694.html
Copyright © 2020-2023  润新知