http://acm.hdu.edu.cn/showproblem.php?pid=6867
InputThe first line contains one integer [Math Processing Error]T [Math Processing Error](1≤T≤100000) — the number of test cases.
The first line of each test case contains only one integer [Math Processing Error]n(1≤n≤5×105) — the number of vertices in the tree.
The second line of each test case contains [Math Processing Error]n−1 integers [Math Processing Error]p2,p3,…,pn(1≤pi<i) — the parent of each non-root node.
The sum of [Math Processing Error]n over all test cases does not exceed [Math Processing Error]106.OutputPrint [Math Processing Error]T integers — for each test case output the maximum number of pairs [Math Processing Error](x,y) that vertices [Math Processing Error]x can move to [Math Processing Error]y after adding one edge.Sample Input
2 5 1 1 2 2 6 1 2 3 1 3
Sample Output
17 26
Sponsor
题意:
给定一棵树,边为父结点指向子结点,添加一条有向边,
使得从某一点A出发能到达一点B的产生的组合<A,B>尽量多
DFS连线求最优
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<bitset> #include<cassert> #include<cctype> #include<cmath> #include<cstdlib> #include<ctime> #include<deque> #include<iomanip> #include<list> #include<map> #include<queue> #include<set> #include<stack> #include<vector> #include <vector> #include <iterator> #include <utility> #include <sstream> #include <limits> #include <numeric> #include <functional> using namespace std; #define gc getchar() #define mem(a) memset(a,0,sizeof(a)) #define debug(x) cout<<"debug:"<<#x<<" = "<<x<<endl; #define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); typedef long long ll; typedef unsigned long long ull; typedef long double ld; typedef pair<int,int> pii; typedef char ch; typedef double db; const double PI=acos(-1.0); const double eps=1e-6; const int inf=0x3f3f3f3f; const int maxn=1e5+10; const int maxm=100+10; const int N=1e6+10; const int mod=1e9+7; int fa[N] = {0} , deep[N] = {0}; int Q[N] = {0}; int ans = -1; int min_ = 0 , n = 0; vector<int> e[N]; void TreeSplitDfs1(int x) { Q[x] = 1; deep[x] = deep[fa[x]] + 1; for(int i = 0;i<N;i++) { int next = e[x][i]; Q[x] += Q[next]; TreeSplitDfs1(next); } min_ += Q[x]; } void TreeSplitDfs2(int x,int dep) { ans = max(ans , dep); for(int i = 0;i<N;i++) { int next = e[x][i]; TreeSplitDfs2(next , dep - Q[next] + n); } } int main() { int i = 0; int t = 0; cin >> t; while(t--) { cin >> n; min_ = 0; ans = 0; i = 0; while(i < n) { i += 1; e[i].clear(); } i = 0; while(i < n) { i += 1; cin >> fa[i+1]; e[fa[i+1]].push_back(i+1); } TreeSplitDfs1(1); TreeSplitDfs2(1 , min_); cout << ans << endl; } return 0; }