SPOJ QTREE4 Query on a tree IV(边分治)

来源:互联网 发布:len在vb中什么意思 编辑:程序博客网 时间:2024/06/06 03:07

看这里

边分治,用堆维护两边的分治的子树(感觉这两个堆的更新用的很巧妙, 然后用链表维护每个点所在的分治结构). 顺便留一份边分治模板

#include <bits/stdc++.h>#include <iostream>#include <cstdio>#include <cmath>#include <cstring>#include <algorithm>using namespace std;#define LL long long #define pii pair<int, int>#define MP make_pair#define inf 0x3f3f3f3f#define N 200010#define M 4000020int fst[N], vv[M], nxt[M], cost[M], e;int f[N], rt, edg, C[N];priority_queue<int> q1[N], q2[N];int sz[N], mx[N], tot, tim;int col[N], lc[N], rc[N], ans[N];int x[N], cx;bool vis[M];void init(){    memset(fst, -1, sizeof fst);    memset(f, -1, sizeof f);    e = 0;}void _add(int u, int v, int c){    vv[e] = v, nxt[e] = fst[u], cost[e] = c, fst[u] = e++;}void add(int u, int v, int c){    vv[e] = v, nxt[e] = f[u], cost[e] = c, f[u] = e++;}void dfsS(int u, int p){    sz[u] = 1;    for(int i = fst[u]; ~i; i = nxt[i]){        int v = vv[i];        if(v == p || vis[i]) continue;        dfsS(v, u);        sz[u] += sz[v];    }}void dfsE(int u, int p, int d){    add(u, tim, d);    x[cx++] = d;    for(int i = fst[u]; ~i; i = nxt[i]){        int v = vv[i], c = cost[i];        if(v == p || vis[i]) continue;        mx[v] = max(sz[v], tot - sz[v]);        if(rt == -1 || mx[v] < mx[rt])            rt = v, edg = i, C[tim] = c;        dfsE(v, u, d + c);    }}   pii find_edge(int u){    dfsS(u, -1);    tot = sz[u], rt = -1, edg = -1, cx = 0;    dfsE(u, -1, 0);     for(int i = 0; i < cx; ++i)        q1[tim].push(x[i]);    return MP(rt, edg);}int top(int k){    while(1){        if(q1[k].empty()) return -inf;        if(q2[k].empty()) return q1[k].top();        if(q1[k].top() == q2[k].top())            q1[k].pop(), q2[k].pop();        else return q1[k].top();    }}void solve(int u){    ++tim;    pii ee = find_edge(u);    if(ee.first == -1){        ans[tim] = 0; return ;    }    int i = ee.second, u1 = vv[i], u2 = vv[i^1];    vis[i] = vis[i^1] = 1;    int cur = tim;    lc[cur] = tim + 1;    solve(u1);    rc[cur] = tim + 1;    solve(u2);    ans[cur] = top(lc[cur]) + top(rc[cur]) + C[cur];    ans[cur] = max(ans[cur], ans[lc[cur]]);    ans[cur] = max(ans[cur], ans[rc[cur]]);}void gao(int u){    for(int i = f[u]; ~i; i = nxt[i]){        int v = vv[i], d = cost[i];        if(col[u]) q1[v].push(d);        else q2[v].push(d);        if(lc[v]){            ans[v] = top(lc[v]) + top(rc[v]) + C[v];            ans[v] = max(ans[v], ans[lc[v]]);            ans[v] = max(ans[v], ans[rc[v]]);        }        else{            if(col[u]) ans[v] = 0;            else ans[v] = -inf;        }    }}int main(){    int n;    scanf("%d", &n);    init();    for(int i = 1; i < n; ++i){        int u, v, c;        scanf("%d%d%d", &u, &v, &c);        _add(u, v, c), _add(v, u, c);    }    tim = 0;    solve(1);    int q, white = n;    scanf("%d", &q);    while(q--){        char s[5];        scanf("%s", s);        if(s[0] == 'A'){            if(white == 0)                puts("They have disappeared.");            else printf("%d\n", ans[1]);        }        else{            int u;            scanf("%d", &u);            gao(u);            if(col[u]) white++;            else white--;            col[u] ^= 1;        }    }    return 0;}
0 0