rt,思路是枚举所有从根节点出发,到达最底下的路径,然后用 s 计算,并排序,取最大的两个,再算出总贡献。
这是赛时想的,但是一直 TLE,赛后一分钟发现这个 sb 在 #define int long long 的情况下使用了 scanf("%d");
不知道会不会 WA 什么的,现在提交不了,代码:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
#define int long long
const int N = 200010;
int T;
int n, k;
int p[N], s[N];
vector<int> v[N];
vector<int> chain[N];
int cnt = 0;
int now[N];
int sum[N];
void dfs(int x, int len) {
if (v[x].size() == 0) {
cnt++; chain[cnt].push_back(1);
for (int i = 1; i <= len; i++) chain[cnt].push_back(now[i]);
return;
}
for (int i = 0; i < v[x].size(); i++) {
int son = v[x][i];
now[len + 1] = son;
dfs(son, len + 1);
}
}
signed main() {
cin >> T;
while (T--) {
scanf("%lld%lld", &n, &k);
for (int i = 1; i <= n; i++) v[i].clear(), chain[i].clear();
for (int i = 2; i <= n; i++) {
scanf("%lld", p + i);
v[p[i]].push_back(i);
}
for (int i = 1; i <= n; i++) scanf("%lld", s + i);
dfs(1, 0);
/*
for (int i = 1; i <= cnt; i++) {
for (int j = 0; j < chain[i].size(); j++) cout << chain[i][j] << " ";
cout << endl;
}
*/
for (int i = 1; i <= cnt; i++) {
sum[i] = 0;
for (int j = 0; j < chain[i].size(); j++)
sum[i] += s[chain[i][j]];
}
sort(sum + 1, sum + 1 + cnt);
int a = sum[cnt], b = sum[cnt - 1];
if (k % 2 == 0) cout << (a + b) * (k / 2) << "\n";
else cout << (k / 2 + 1) * a + (k / 2) * b << "\n";
}
return 0;
}