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 (1≤T≤100000) — the number of test cases.
The first line of each test case contains only one integer n(1≤n≤5×105) — the number of vertices in the tree.
The second line of each test case contains n−1 integers p2,p3,…,pn(1≤pi<i) — the parent of each non-root node.
The sum of n over all test cases does not exceed 106.
The first line of each test case contains only one integer n(1≤n≤5×105) — the number of vertices in the tree.
The second line of each test case contains n−1 integers p2,p3,…,pn(1≤pi<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 }

浙公网安备 33010602011771号