《CF767C Garland》
难顶,这题其实不难,但是细节问题出的有点多。
考虑删的两条边的相对位置,如果他们的LCA不等于他们,那么很显然就是LCA的两个子树里删边。
如果LCA = 其中一条边,那么就有LCA = 2 * average,然后子树内再删一条。这里记录一下子树里 = average / 3的即可。
emmm细节有点多。
// Author: levil #include<bits/stdc++.h> using namespace std; typedef long long LL; typedef unsigned long long ULL; typedef long double ld; typedef pair<int,int> pii; const int N = 1e6 + 5; const int M = 1e4 + 5; const LL Mod = 998244353; #define rep(at,am,as) for(int at = am;at <= as;++at) #define ret(at,am,as) for(int at = am;at >= as;--at) #define INF 1e9 #define dbg(ax) cout << "now this num is " << ax << endl; inline long long ADD(long long x,long long y) { if(x + y < 0) return ((x + y) % Mod + Mod) % Mod; return (x + y) % Mod; } inline long long MUL(long long x,long long y) { if(x * y < 0) return ((x * y) % Mod + Mod) % Mod; return x * y % Mod; } inline long long DEC(long long x,long long y) { if(x - y < 0) return (x - y + Mod) % Mod; return (x - y) % Mod; } int n,rt,val[N],now,dp[N],vis[N]; vector<pii> G[N]; void dfs(int u,int fa,int id) { dp[u] = val[u]; vector<int> vec; for(auto v : G[u]) { if(v.first == fa) continue; dfs(v.first,u,v.second); if(vis[v.first]) vec.push_back(vis[v.first]); dp[u] += dp[v.first]; } if(vec.size() > 1) { printf("%d %d\n",vec[0],vec[1]); exit(0); } else if(u != rt && dp[u] == 2 * now && vec.size() > 0) { printf("%d %d\n",id,vec[0]); exit(0); } if(dp[u] == now) vis[u] = id; else if(vec.size() > 0) vis[u] = vec[0]; } void solve() { scanf("%d",&n); int sum = 0; rep(i,1,n) { int x,y;scanf("%d %d",&x,&y); val[i] = y; if(x == 0) rt = i; else { G[x].push_back(pii{i,i}); G[i].push_back(pii{x,i}); } sum += val[i]; } if(sum % 3 != 0) {printf("-1\n");exit(0);} now = sum / 3; dfs(rt,0,0); printf("-1\n"); } int main() { //int _; //for(scanf("%d",&_);_;_--) { solve(); //} system("pause"); return 0; } /* 3 0 1 1 2 1 3 */