标签:
1 7 3 1 2 1 3 2 4 2 5 3 6 3 7 2 3 4 4 5 3 6 7 3
6HintStack expansion program: #pragma comment(linker, "/STACK:1024000000,1024000000")
#pragma comment(linker, "/STACK:1024000000,1024000000") #include <iostream> #include <cstring> #include <cstdio> #include <vector> #include <algorithm> using namespace std; #define prt(k) cerr<<#k" = "<<k<<endl typedef unsigned long long ll; const int N = 233333; int n, m, head[N], mm; struct Edge { int v, next, w; } e[N << 1]; void add(int u, int v, int w = 1) { e[mm].v = v; e[mm].next = head[u]; e[mm].w = w; head[u] = mm++; } int sz[N], dep[N]; int f[N][22]; /// f[i][j] 表示 i 的第 2^j 个祖先 int dfn[N]; ///dfs index int cur; int id[N]; /// you dfs xu qiu chu bian hao int len[N]; int fa[N], son[N], top[N], p[N], pos; /// fa 父节点 dep -- 深度 sz 孩子数 son 重儿子 /// top[u] 它所在重链顶端节点 p[u]在数据结构中位置 rp p的反 void dfs(int u, int pre = 1) /// 点从 1 开始标号 { sz[u] = 1; dfn[u] = ++cur; id[cur] = u; for (int i=head[u]; ~i; i=e[i].next) { int v = e[i].v; int w = e[i].w; if (v != pre) { dep[v] = dep[u] + 1; len[v] = len[u] + w; fa[v] = f[v][0] = u; dfs(v, u); sz[u] += sz[v]; if (son[u]==-1 || sz[son[u]] < sz[v]) son[u] = v; } } } /// top[u] 它所在重链顶端节点 p[u]在数据结构中位置 void getpos(int u, int v = 1) { top[u] = v; p[u] = ++pos; if (~son[u]) getpos(son[u], v); for (int i=head[u]; ~i; i=e[i].next) { int v= e[i].v; if (v-son[u] && v-fa[u]) getpos(v, v); } } int maxh; void gao() { cur = 0; dep[0] = -1; len[1] = dep[1] = 0; memset(son, -1, sizeof son); dfs(1, 0); int j; for (j=1; (1<<j)<n; j++) for (int i=1; i<=n; i++) f[i][j] = f[f[i][j-1]][j-1]; maxh = j - 1; getpos(1); } int swim(int x, int k) { for (int i=0; i<=maxh; i++) if (k >> i & 1) x = f[x][i]; return x; } int LCA(int x, int y) { if (dep[x] > dep[y]) swap(x, y); ///dep[x] <= dep[y]; y = swim(y, dep[y] - dep[x]); if (x == y) return y; for (int i=maxh; i>=0; i--) { if (f[x][i] != f[y][i]) x = f[x][i], y = f[y][i]; } return f[x][0]; } int lca[N]; struct P { int u, v, w; P() {} P(int _u,int _v, int _w) {u=_u, v=_v, w=_w;} } chain[N]; /// chains; /******Bit Index Tree************/ struct Tree { int tree[N<<2]; void init() { memset(tree, 0, sizeof tree); } inline int low(int x) { return x & -x; } void Add(int i, int x) { for(; i<=n; i+=low(i)) tree[i]+=x; } int sum(int p) { int res = 0; for(int i=p; i>0; i-=low(i)) res+=tree[i]; return res; } int query(int l, int r) { if (l > r) swap(l, r); return sum(r) - sum(l-1); } } Td, Tsum; /**********End Tree**********/ inline int get_sum(int u, int v) { int f1 = top[u], f2 = top[v]; int tmp = 0; int sum, d; while(f1 - f2) { if(dep[f1] < dep[f2]) { swap(f1 ,f2); swap(u, v); } sum += Tsum.query(p[f1], p[u]); d += Td.query(p[f1], p[u]); u = fa[f1]; f1 = top[u]; } sum += Tsum.query(p[u], p[v]); d += Td.query(p[u], p[v]); return sum - d; } vector<int> vi[N]; /// vi[i] 存储以 i 为端点LCA的链编号 int d[N], sum[N]; void init() { pos =0 ; mm = 0; memset(head,-1,sizeof head); memset(son, -1, sizeof son); for (int i=0;i<N;i++) vi[i].clear(); Tsum.init(); Td.init(); memset(d ,0 , sizeof d); } void DP(int u, int fa = 1) { sum[u] = 0; for (int i=head[u];~i;i=e[i].next) { int v = e[i].v; if (v==fa) continue; DP(v, u); sum[u] += d[v]; } d[u] = sum[u]; Tsum.Add(p[u], sum[u]); for (int p : vi[u]) { int a = chain[p].u; int b = chain[p].v; int w = chain[p].w; d[u] = max(d[u], w + get_sum(a, b)); } Td.Add(p[u], d[u]); } int main() { int re; scanf("%d", &re); while (re--) { scanf("%d%d", &n, &m); init(); for (int i=0; i<n-1; i++) { int u, v; scanf("%d%d", &u, &v); add(u, v); add(v, u); } gao(); for (int i=0; i<m; i++) { int u, v , w; scanf("%d%d%d", &u, &v, &w); lca[i] = LCA(u,v); vi[lca[i]].push_back(i); chain[i] = P(u, v, w); } DP(1, 1); printf("%d\n", d[1]); } }
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:
原文地址:http://blog.csdn.net/oilover/article/details/47054549