Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include<bits/stdc++.h>
- using namespace std;
- void read(int &x)
- { scanf("%d", &x); }
- void write(int x)
- { printf("%d", x); }
- void maximize(int &a, int b)
- { a = max(a, b); }
- const int N = 1e5 + 10;
- const int Nlog = 17;
- const int inf = 1e9 + 7;
- int n, Q;
- vector<int > adj[N];
- struct QUERY { int u, v, c; } queri[N];
- vector<pair<int, int > > listOfLCA[N];
- vector<int > listOfQueri[N];
- struct LowestCommonAncestor {
- int dad[N][Nlog];
- int dep[N];
- void dfs(int u, int papa){
- for (int v : adj[u])
- if (v == papa) continue;
- else
- dad[v][0] = u,
- dep[v] = dep[u] + 1,
- dfs(v, u);
- }
- void build(){
- dep[1] = 1;
- dfs(1, 0);
- for (int j = 1; j < Nlog; j++)
- for (int i = 1; i <= n; i++)
- dad[i][j] = dad[ dad[i][j - 1] ][ j - 1 ];
- }
- int getLCA(int u, int v){
- if (dep[u] < dep[v]) swap(u, v);
- for (int i = Nlog - 1; i >= 0; i--)
- if (dep[ dad[u][i] ] >= dep[v]) u = dad[u][i];
- if (u == v) return u; assert(dep[u] == dep[v]);
- for (int i = Nlog - 1; i >= 0; i--)
- if (dad[u][i] != dad[v][i])
- u = dad[u][i],
- v = dad[v][i];
- return dad[u][0];
- }
- int dadKth(int u, int dist){
- if (dist < 0) return u;
- for (int jump = Nlog - 1; jump >= 0; jump--)
- if (dist & (1 << jump))
- u = dad[u][jump];
- return u;
- }
- } LCA;
- void init(){
- LCA.build();
- for (int i = 1; i <= n; i++)
- for (int j = 0; j < Nlog; j++)
- listOfLCA[ LCA.dad[i][j] ] . push_back({i, j});
- for (int i = 1; i <= Q; i++){
- int lca = LCA.getLCA(queri[i].u, queri[i].v);
- listOfQueri[lca].push_back(i);
- }
- }
- struct DynamicProgramming{
- int F[N][2];
- int specSum[N][Nlog];
- int getMax(int u)
- { return max(F[u][0], F[u][1]); }
- int getSumSpecRange(int u, int v){
- if (LCA.dep[u] < LCA.dep[v]) return -inf;
- int ans = 0;
- for (int jump = Nlog - 1; jump >= 0; jump--)
- if (LCA.dep [ LCA.dad[u][jump] ] >= LCA.dep[v]){
- ans += specSum[u][jump];
- u = LCA.dad[u][jump];
- }
- return ans;
- }
- void dfs(int u, int papa){
- for (int v : adj[u])
- if (v == papa) continue;
- else {
- dfs(v, u);
- F[u][0] += getMax(v);
- }
- // update Dp
- for (int queriIndex : listOfQueri[u]){
- int qu = queri[queriIndex].u,
- qv = queri[queriIndex].v,
- qc = queri[queriIndex].c;
- if (LCA.dep[qu] < LCA.dep[qv]) swap(qu, qv);
- // qu nam o duoi qv
- int lca = LCA.getLCA(qu, qv);
- int preLCA1 = LCA.dadKth(qu, LCA.dep[qu] - LCA.dep[lca] - 1);
- int preLCA2 = LCA.dadKth(qv, LCA.dep[qv] - LCA.dep[lca] - 1);
- if (lca != qv){
- maximize(F[u][1], qc + F[u][0] - getMax(preLCA1) - getMax(preLCA2) +
- getSumSpecRange(qu, preLCA1) + getSumSpecRange(qv, preLCA2) + F[qu][0] + F[qv][0]);
- }
- else{
- maximize(F[u][1], qc + F[u][0] - getMax(preLCA1) +
- getSumSpecRange(qu, preLCA1) + F[qu][0]);
- }
- }
- // update SpecSum
- for (pair<int, int > lcaInformation : listOfLCA[u]){
- int jump = lcaInformation.second,
- descendant = lcaInformation.first;
- if (jump == 0) specSum[descendant][jump] = F[u][0] - getMax(descendant);
- else
- specSum[descendant][jump] =
- specSum[descendant][jump - 1] + specSum[ LCA.dad[descendant][jump - 1] ] [ jump - 1];
- }
- }
- void build(){
- dfs(1, 0);
- }
- } DP;
- void solve(){
- DP.build();
- write(DP.getMax(1));
- }
- main(){
- freopen("election.in", "r", stdin);
- freopen("election.out", "w", stdout);
- read(n);
- for (int i = 1; i < n; i++){
- int a, b; read(a); read(b);
- adj[a].push_back(b);
- adj[b].push_back(a);
- }
- read(Q);
- for (int i = 1; i <= Q; i++)
- read(queri[i].u),
- read(queri[i].v),
- read(queri[i].c);
- init();
- solve();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement