zoukankan      html  css  js  c++  java
  • [hdu-6867]Tree 树上前缀和 2020多校9

    【题目链接】:http://acm.hdu.edu.cn/showproblem.php?pid=6867

    【题目】:

    Problem Description
    You are given a tree consisting of n vertices numbered 1 to n rooted at node 1. The parent of the i-th vertices is pi. You can move from a vertex to any of its children. What's more, you can add one directed edge between any two different vertices, and you can move through this edge too. You need to maximize the number of pairs (x,y) such that x can move to y through the edges after adding the edge. Note that x can also move to x.
     
    Input
    The first line contains one integer T (1T100000) — the number of test cases.
    The first line of each test case contains only one integer n(1n5×105) — the number of vertices in the tree.
    The second line of each test case contains n1 integers p2,p3,,pn(1pi<i) — the parent of each non-root node.
    The sum of n over all test cases does not exceed 106.
     
    Output
    Print T integers — for each test case output the maximum number of pairs (x,y) that vertices x can move to y after adding one edge.
     
    Sample Input
    2 5 1 1 2 2 6 1 2 3 1 3
     Sample Output
    17 26
     
    Source
     

    【题意】:给一个根节点为1的树,每个点可以走向它的儿子。现在你可以加一条有向边。求加完边后最大的能到达的 点对数(x,y)(x可以走到y)。

    【题解】:

    根节点能到达所有点,所以使某个点到达根节点相当于能到达所有点。
    有向边肯定是从某个叶子结点连向根节点,可以使叶子结点到根节点这条路上的点都能从根节点到达这课树上的所有点。

    原来的答案preans有两种计算方法:
    1.每个点能到的点等于以他为根的子树大小tson[x]
    2.每个点对答案的贡献是它的深度deep[x](能到它的点的数量)。

    加上有向边后,从跟到这个叶子结点的点都要对答案进行更新,加上 n-tson[x];
    我们可以用树上前缀和qian[x]求出 叶子到根的tson和
    则答案结果就是对所有叶子结点x,取 preans+max(n*deep[x]-qian[x]);

    ps:答案并不是直接从深度最深的叶子结点连到根(比赛第一发直接这样写了wa掉(计算公式都推出来了却没求所有叶子结点真的蠢哭了)),因为可能这棵子树很大,让这条链上的点走到所有点并不能贡献更多。所以必须把所有叶子结点的结果都算出来取max。

    【AC代码】

    #include<bits/stdc++.h>
    using namespace std;
    int const maxn=5e5+10;
    long long inf=-1e17;
    int tot,head[maxn],n,deep[maxn],tson[maxn],hson,fa[maxn];
    long long qian[maxn];
    long long ans=0,getmi;
    struct edge{
        int v,nxt;
    }e[maxn<<1];
    void build(int x,int y){
        e[++tot].v=y;
        e[tot].nxt=head[x];
        head[x]=tot;
    }
    void TreeSplitDfs1(int x,int d){
        deep[x]=d;
        if(d>deep[hson])hson=x;
        tson[x]=1;
        ans+=d;
        for(int i=head[x];i;i=e[i].nxt){
            int v=e[i].v;
            TreeSplitDfs1(v,d+1);
            tson[x]+=tson[v];
        }
    }
    void TreeSplitDfs2(int x){
        qian[x]=qian[fa[x]]+tson[x];
        for(int i=head[x];i;i=e[i].nxt){
            TreeSplitDfs2(e[i].v);
        }
        if(head[x]==0){
            qian[x]=(long long )deep[x]*(long long )n-qian[x];
            getmi=max(getmi,qian[x]);
        }
    }
    int main(){
        int t;
        scanf("%d",&t);
        fa[1]=0;
        qian[0]=0;
        while(t--){
            scanf("%d",&n);
            ans=0;tot=0;hson=0;
            getmi=inf;
            memset(head,0,sizeof(int)*(n+5));
            for(int i=2;i<=n;i++){
                scanf("%d",&fa[i]);
                build(fa[i],i);
            }
            TreeSplitDfs1(1,1);
            TreeSplitDfs2(1);
            ans+=getmi;
            printf("%lld
    ",ans);
        }
        return 0;
    }
    /*
    14
    1 1 2 2 3 3 3 3 3 3 3 7 5
    */
  • 相关阅读:
    美国常青小组:“4+2”,成功的企业的普遍特征
    与你的商业伙伴建立信任关系的12条准则
    成功12级跳:你还是穷人只因为你没有立下成为富人的目标
    生日与谁共
    猎取人心的36条黄金法则
    谢谢你能为我落泪
    要锤炼出营销魔法,口碑营销“无招胜有招”
    怎样成为下一个比尔·盖茨?总结决定他成功的几大要素
    只要你能够幸福
    史玉柱:创业不是靠忽悠,我的最后四个忠告
  • 原文地址:https://www.cnblogs.com/conver/p/13525406.html
Copyright © 2011-2022 走看看