2020杭电多校第九场 A:Tree

Tree

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)


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

题解

  从一个点出发可以到达他的所有子节点和他自己,添加一条边使得(x,y)(从x到y)最多,添加的这条边的终点最好的情况就是连一个子节点最多的点,也就是直接连到根节点1是最优的情况,一个点x向根节点连一条边,假设x有sx个子节点,从x可以新增n-sx个新的(x,y)对,假设从他的父亲作为起点新增边可以新增tmp个点对,则从x可以总共新增n-sx+tmp个点对。所以问题可以变为找出一个点使新增的点对最多。

  1 #pragma GCC optimize(3,"Ofast","inline")
  2 #include <map>
  3 #include <set>
  4 #include <time.h>
  5 #include <stack>
  6 #include <queue>
  7 #include <cmath>
  8 #include <vector>
  9 #include <cstdio>
 10 #include <string>
 11 #include <cstring>
 12 #include <iostream>
 13 #include <algorithm>
 14 #define fi first
 15 #define se second
 16 #define IL inline
 17 #define RG register
 18 #define MP(a,b) make_pair(a,b)
 19 #define PI acos(-1)
 20 #define Mod 998244353
 21 #define EPS 1e-5
 22 using namespace std;
 23 typedef long long LL;
 24 typedef unsigned long long ULL;
 25 typedef double DB;
 26 typedef pair<int, int> PR;
 27 const int N = 500009;
 28 const int M = 400009;
 29 int gx[] = {0, 0, 1, -1};
 30 int gy[] = {1, -1, 0, 0};
 31 int n, m, k;
 32 vector<int> g[N];
 33 LL size[N], f[N], sum, ans;
 34 class Init
 35 {
 36     public:
 37         IL int mabs(int x)
 38         {
 39             return x < 0 ? -x : x;
 40         }
 41         IL LL gcd(LL a, LL b)
 42         {
 43             return b == 0 ? a : gcd(b, a%b);
 44         }
 45         IL LL lcm(int a, int b)
 46         {
 47             return a * b / gcd(a, b);
 48         }
 49         IL LL ksm(LL a, LL b)
 50         {
 51             LL tmp = a, sum = 1;
 52             while(b)
 53             {
 54                 if(b & 1)
 55                     sum = (sum * tmp) % Mod;
 56                 tmp = (tmp * tmp) % Mod;
 57                 b >>= 1;
 58             }
 59             return sum % Mod;
 60         }
 61         IL LL read()
 62         {
 63             LL num = 0; bool flag = 0; char c;
 64             while((c=getchar())==' ' || c=='\n' || c=='\r');
 65             if(c == '-') flag = 1; else num = c - '0';
 66             while(isdigit(c=getchar()))
 67                 num = num * 10LL + c - '0';
 68             return flag ? -num : num;
 69         }
 70         IL void print(LL x)
 71         {
 72             if(x < 0) putchar('-'), x = -x;
 73             if(x > 9) print(x/10);
 74             putchar(x%10+'0');
 75         }
 76     private:
 77 
 78 }Init;
 79 void dfs(int x)
 80 {
 81     size[x] = 1;
 82     for(int i = 0; i < g[x].size(); i++)
 83     {
 84         dfs(g[x][i]);
 85         size[x] += size[g[x][i]];
 86     }
 87 }
 88 void geta(int x, int fa)
 89 {
 90     sum += size[x];
 91     f[x] = 1LL * n - size[x] + f[fa];
 92     ans = max(ans, f[x]);
 93     for(int i = 0; i < g[x].size(); i++)
 94         geta(g[x][i], x);
 95 }
 96 int main(void)
 97 {
 98     int T = Init.read();
 99     while(T--)
100     {
101         n = Init.read();
102         for(int i = 1; i <= n; i++)
103             g[i].clear(), f[i] = 0;
104         for(int i = 2; i <= n; i++)
105         {
106             int p = Init.read();
107             g[p].push_back(i);
108         }
109         dfs(1);
110         ans = 0; sum = 0;
111         geta(1, 0);
112         printf("%lld\n", ans+sum);
113     }
114     return 0;
115 }
View Code

 

posted @ 2020-08-18 17:29  Johnny-English  阅读(275)  评论(0)    收藏  举报