标签:
http://acm.hdu.edu.cn/showproblem.php?pid=5296
实际上问题可以转化为点到一个连通子树的最短距离。。
//Hello. I‘m Peter.
#pragma comment(linker, "/STACK:102400000,102400000")
#include<cstdio>
#include<iostream>
#include<sstream>
#include<cstring>
#include<string>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<functional>
#include<cctype>
#include<ctime>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<map>
using namespace std;
typedef long long ll;
inline int read(){
int x=0,f=1;char ch=getchar();
while(ch>‘9‘||ch<‘0‘){if(ch==‘-‘)f=-1;ch=getchar();}
while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();}
return x*f;
}
#define N 100010
int n, q;
struct Edge{
int from, to, next;
int v;
}edge[N << 1];
int head[N],numedge;
void add_edge(int from, int to, int v){
int t= ++ numedge;
edge[t].from = from;
edge[t].to = to;
edge[t].v = v;
edge[t].next = head[from];
head[from] = t;
}
int d[N], vto[N], rvto[N], fa[N], dep[N], dfsclo;
void get_d(int now, int father){
vto[now] = ++dfsclo;
rvto[dfsclo] = now;
for(int i = head[now]; i != -1; i = edge[i].next){
int to = edge[i].to;
if(to == father) continue;
fa[to] = now;
dep[to] = dep[now] + 1;
d[to] = d[now] + edge[i].v;
get_d(to, now);
}
}
int lca[N][20];
void init_lca(){
for(int i = 1; i <= n; i++) lca[i][0] = fa[i];
for(int j = 1; 1<<j <= n; j++){
for(int i = 1; i <= n; i++){
lca[i][j] = -1;
if(lca[i][j-1] != -1){
lca[i][j] = lca[ lca[i][j-1] ][j-1];
}
}
}
}
int query_lca(int a, int b){
if(dep[a] < dep[b]) swap(a, b);
int log;
for(log = 0; 1<<log <= n; log++);
log--;
for(int i = log; i >=0; i--){
if(lca[a][i] != -1 && dep[ lca[a][i] ] >= dep[b]) a = lca[a][i];
}
if(a == b) return a;
for(int i = log; i >=0; i--){
if(lca[a][i] != -1 && lca[b][i] != -1 && lca[a][i] != lca[b][i]){
a = lca[a][i];
b = lca[b][i];
}
}
return fa[a];
}
set<int>se;
int v1, v2;
void findv1v2(int v){
if(vto[v] < *se.begin() || vto[v] > *(--se.end()) ){
v1 = *se.begin();
v2 = *(--se.end());
}
else{
v1 = *se.lower_bound(vto[v]);
v2 = *(--se.upper_bound(vto[v]));
}
v1 = rvto[v1];
v2 = rvto[v2];
}
int main(){
//freopen("data.txt","r",stdin);
int T = read();
for(int kase = 1; kase <= T; kase ++){
printf("Case #%d:\n",kase);
n = read(), q = read();
for(int i =1 ; i <= n ;i++) head[i] = -1;
numedge = 0;
for(int i = 1; i < n; i++){
int a, b, v;
a = read();
b = read();
v = read();
add_edge(a, b, v);
add_edge(b, a, v);
}
dep[1] = 0;
fa[1] = -1;
dfsclo = 0;
d[1] = 0;
get_d(1, 0);
init_lca();
// for(int i = 1; i <= n; i++){
// for(int j = 1; j <= n; j++){
// printf("lca(%d ,%d) = %d\n",i,j,query_lca(i, j));
// }
// }
int ans = 0;
se.clear();
for(int iq = 1; iq <= q; iq++){
int a, v;
a = read(), v = read();
if(a == 1){
if(se.find(vto[v]) == se.end()){
if(!se.empty()){
findv1v2(v);
ans += d[v] - d[query_lca(v, v1)] - d[query_lca(v, v2)] + d[query_lca(v1, v2)];
}
else ans = 0;
se.insert(vto[v]);
}
}
else{
if(se.find(vto[v]) != se.end()){
se.erase(vto[v]);
if(!se.empty()){
findv1v2(v);
ans -= d[v] - d[query_lca(v, v1)] - d[query_lca(v, v2)] + d[query_lca(v1, v2)];
}
else ans = 0;
}
}
//printf("v = %d v1 = %d v2 = %d\n",v,v1 ,v2);
printf("%d\n",ans);
}
}
return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:
原文地址:http://blog.csdn.net/uestc_peterpan/article/details/47008953