답안 #297581

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
297581 2020-09-11T16:07:08 Z limabeans Election Campaign (JOI15_election_campaign) C++17
0 / 100
417 ms 115420 KB
#include <bits/stdc++.h>
using namespace std;

template<typename T>
void out(T x) { cout << x << endl; exit(0); }
#define watch(x) cout << (#x) << " is " << (x) << endl





using ll = long long;

const ll mod = 1e9+7;
const int maxn = 1e6 + 5;
const int LOG = 20;

int n, m;
vector<int> g[maxn];
int dep[maxn];
int par[maxn][LOG+1];
vector<int> leaves[maxn];
ll dp0[maxn]; // no path goes direct thru me
ll dp1[maxn]; // path goes directly thru me
vector<ll> dp[maxn]; // no path thru me, and no path thru ith leaf


void gen(int at, int p) {
    for (int j=1; j<LOG; j++) {
	par[at][j] = par[par[at][j-1]][j-1];
    }
    for (int to: g[at]) {
	if (to==p) continue;
	leaves[at].push_back(to);
	par[to][0]=at;
	dep[to]=1+dep[at];
	gen(to,at);
    }
}

int lca(int x, int y) {
    if (dep[x]<dep[y]) swap(x,y);
    int dx=dep[x]-dep[y];
    for (int j=0; j<LOG; j++) {
	if (dx>>j&1) {
	    x=par[x][j];
	}
    }
    if (x==y) return x;

    for (int j=LOG-1; j>=0; j--) {
	if (par[x][j] != par[y][j]) {
	    x=par[x][j];
	    y=par[y][j];
	}
    }

    return par[x][0];    
}

int a[maxn], b[maxn];
ll c[maxn];
vector<int> qu[maxn];


void procQuery(int i) {
    int from = a[i];
    int to = b[i];

    int mid = lca(from, to);
    qu[mid].push_back(i);
}


void dfs(int at) {
    for (int to: leaves[at]) {
	dfs(to);
	dp0[at] += max(dp0[to], dp1[to]);
    }
    int lcount = leaves[at].size();
    dp[at].resize(lcount);
    for (int i=0; i<lcount; i++) {
	for (int j=0; j<lcount; j++) {
	    if (i == j) continue;
	    int to = leaves[at][j];
	    dp[at][i] += max(dp0[to], dp1[to]);
	}
    }


    for (int qi: qu[at]) {
	vector<vector<int>> paths;
	// get paths a->at and at<-b
	for (int nd: {a[qi],b[qi]}) {
	    if (nd==at) continue;
	    vector<int> path = {nd};
	    while (par[nd][0] != at) {
		nd=par[nd][0];
		path.push_back(nd);
	    }
	    reverse(path.begin(), path.end());
	    paths.push_back(path);
	}
	ll cur = c[qi];
	
	for (int to: leaves[at]) {
	    int id=-1;
	    for (int j=0; j<int(paths.size()); j++) {
		if (paths[j].front() == to) {
		    id = j;
		}
	    }

	    // at->to->...a
	    if (~id) {
		auto &p = paths[id];
		if ((int)p.size() == 1) {
		    int end = p[0];
		    cur += dp0[end];
		} else {
		    int nid = 0;
		    while (leaves[p[0]][nid] != p[1]) nid++;
		    cur += dp[p[0]][nid];
		}
	    } else {
		cur += max(dp0[to],dp1[to]);
	    }
	}

	dp1[at] = max(dp1[at], cur);
    }
}

int main() {
    ios_base::sync_with_stdio(false); cin.tie(0);  cout.tie(0);

    cin>>n;
    for (int i=0; i<n-1; i++) {
	int u,v;
	cin>>u>>v;
	--u; --v;
	g[u].push_back(v);
	g[v].push_back(u);
    }

    gen(0,0);

    cin>>m;
    for (int i=0; i<m; i++) {
	cin>>a[i]>>b[i]>>c[i];
	--a[i];
	--b[i];
	procQuery(i);
    }


    dfs(0);
    ll res = max(dp0[0], dp1[0]);
    cout<<res<<endl;    
    return 0;
}
# 결과 실행 시간 메모리 Grader output
1 Correct 65 ms 94328 KB Output is correct
2 Correct 65 ms 94456 KB Output is correct
3 Incorrect 65 ms 94400 KB Output isn't correct
4 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 67 ms 94328 KB Output is correct
2 Incorrect 69 ms 94328 KB Output isn't correct
3 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 67 ms 94328 KB Output is correct
2 Incorrect 69 ms 94328 KB Output isn't correct
3 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 417 ms 115420 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 65 ms 94328 KB Output is correct
2 Correct 65 ms 94456 KB Output is correct
3 Incorrect 65 ms 94400 KB Output isn't correct
4 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 65 ms 94328 KB Output is correct
2 Correct 65 ms 94456 KB Output is correct
3 Incorrect 65 ms 94400 KB Output isn't correct
4 Halted 0 ms 0 KB -