题意:有一棵由n个点构成的树,只能从父节点走向子节点,那么当从点x到y就形成数对(x,y)。加一条有向边使数对的个数最多。
思路:将一个点连接根节点,这样该点就可以到达所有点可获得最大值,运用dfs算法解决。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
template <typename T> bool chkmax(T &x,T y)
{
return x<y?x=y,true:false;
}
template <typename T> bool chkmin(T &x,T y)
{
return x>y?x=y,true:false;
}
ll ans = 0;
int n,tot;
int h[1000005],v[1000005],nxt[1000005],dep[1000005],siz[1000005];
//读入整数
int readint(){
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;
}
void addedge(int x,int y){
v[++tot] = y;
nxt[tot] = h[x];
h[x] = tot;
}
//dfs
void dfs1(int u){
siz[u] = 1;
for(int p=h[u];p;p=nxt[p]){
dep[v[p]] = dep[u] +1;
dfs1(v[p]);
siz[u] += siz[v[p]];
}
}
//dfs
void dfs2(int u,ll k){
chkmax(ans,k);
for(int p = h[u];p;p = nxt[p])
dfs2(v[p],k+n-siz[v[p]]);
}
int main(){
int tcase = readint();
while(tcase--){
n = readint();
for(int i=1;i<=n;i++){
h[i] = 0;
tot = 0;
}
for(int i=2;i<=n;i++){
addedge(readint(),i);
}
ans = 0;
dep[1] = 0;
dfs1(1);
dfs2(1,0);
for(int i = 1;i<=n;i++){
ans+=siz[i];
}
cout<<ans<<endl;
}
return 0;
}