大体题意:
给你一颗树,要求切掉两个边,使得剩下的三个子树权值相同,问切哪两个边? 没有输出-1
思路:
因为第一次删除肯定是删除一个完整子树。
所以直接统计出每个点包含的完整子树的权值之和, 发现一个点的权值之和等于sum/3 的话,就把它切掉,直到切掉两个为止。
注意:
切掉之后点的权值之和会发生改变。
其次 根节点不能被切。
#include <bits/stdc++.h>
#define mr make_pair
#define ps push_back
#define fi first
#define se second
#define Siz(x) (int)x.size()
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
const double eps = 1e-10;
const int inf = 0x3f3f3f3f;
const double pi = acos(-1.0);
const int maxn = 1e6 + 10;
vector<int>g[maxn];
int sum = 0;
int dp[maxn],w[maxn], n;
int root, ans[2];
void dfs(int cur){
dp[cur] = w[cur];
for (int i = 0; i < Siz(g[cur]); ++i){
int v = g[cur][i];
dfs(v);
dp[cur] += dp[v];
}
if (dp[cur] == sum && cur != root ){
if (ans[0] == 0) ans[0] = cur,dp[cur] = 0;
else if (ans[1] == 0)ans[1] = cur,dp[cur] = 0;
}
}
int main(){
scanf("%d",&n);
for (int i = 1; i <= n; ++i){
int u,v;
scanf("%d %d",&u, &v);
g[u].ps(i);
w[i] = v;
if (u == 0) root = i;
sum += v;
}
if (sum % 3) return 0 * puts("-1");
sum /= 3;
dfs(root);
if (ans[0] == 0 || ans[1] == 0) return 0 * puts("-1");
printf("%d %d\n",ans[0], ans[1]);
return 0;
}
/**
6
2 4
0 -1
4 2
2 3
1 2
4 5
**/