第一行有一个整数 N,表示点的个数;
接下来 N-1 行每行三个整数 x,y,z,表示点 x 和 y 之间有一条长度为 z 的双向边;
第 N+1 行有一个正整数 M;
接下来 M 行每行是一个事件,事件是以下三种格式之一:
+ x:表示点 x 上出现了异象石;
- x:表示点 x 上的异象石被摧毁;
?:表示询问使当前所有异象石所在的点连通所需的边集的总长度最小是多少。
输出格式
对于每个 ? 事件,输出一个整数表示答案。
样例
样例输入
6
1 2 1
1 3 5
4 1 7
4 5 3
6 4 2
10
+ 3
+ 1
?
+ 6
?
+ 5
?
- 6
- 3
?
样例输出
5
14
17
10
代码:
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<queue>
#include<set>
#include<ctime>
#define maxn 100005
#define maxx 18
#define ll long long
using namespace std;
int head[maxn],_next[maxn<<1],to[maxn<<1],w[maxn<<1];
int edge;
void addEdge(int x,int y,int z)
{
to[++edge]=y,w[edge]=z,_next[edge]=head[x],head[x]=edge;
to[++edge]=x,w[edge]=z,_next[edge]=head[y],head[y]=edge;
}
int d[maxn];
ll dis[maxn];
queue<int>que;
int n,m,N;
int f[maxn][maxx];
void bfs()
{
d[1]=1;
que.push(1);
while(que.size())
{
int u=que.front();que.pop();
for(int i=head[u];i;i=_next[i])
{
int v=to[i];
if(d[v])continue;
d[v]=d[u]+1;
dis[v]=dis[u]+w[i];
f[v][0]=u;
for(int i=1;i<=N;i++)
f[v][i]=f[f[v][i-1]][i-1];
que.push(v);
}
}
}
int lca(int a,int b)
{
if(d[a]>d[b])swap(a,b);
for(int i=N;i>=0;i--)
if(d[a]<=d[f[b][i]])b=f[b][i];
if(a==b)return a;
for(int i=N;i>=0;i--)
if(f[a][i]!=f[b][i])a=f[a][i],b=f[b][i];
return f[a][0];
}
ll getRoad(int a,int b)
{
return dis[a]+dis[b]-2*dis[lca(a,b)];
}
int dfn[maxn],ind;
void dfs(int u,int fa)
{
dfn[u]=++ind;
for(int i=head[u];i;i=_next[i])
{
int v=to[i];
if(v==fa)continue;
dfs(v,u);
}
}
void init()
{
//memset(head,0,sizeof(head));
edge=0;
N=(int)log2(n)+1;
}
struct cmp
{
bool operator() (const int&a,const int&b)
{
return dfn[a]<dfn[b];
}
};
set<int,cmp>_set;
int main()
{
//cout<<log2(maxn)<<endl;
cin>>n;
init();
int x,y,z;
for(int i=1;i<n;i++)
{
scanf("%d%d%d",&x,&y,&z);
addEdge(x,y,z);
}
//clock_t start,finish;
//start=clock();
bfs();
dfs(1,0);
char s[5];
cin>>m;
ll ans=0;
set<int,cmp>::iterator it,_it;
while(m--)
{
scanf("%s",s);
if(s[0]=='?')
printf("%lld\n",ans/2);
else
{
scanf("%d",&x);
if(s[0]=='+')
{
_set.insert(x);
if(_set.size()>1)
{
it=_set.find(x);
_it=_set.end();
_it--;
int l,r;
if(it==_set.begin())l=*(_it);
else
{
it--;l=*it;it++;
}
it++;
if(it==_set.end())r=*(_set.begin());
else r=*it;
ans-=getRoad(l,r);ans+=getRoad(l,x);ans+=getRoad(x,r);
}
}
else
{
if(_set.size()>1)
{
it=_set.find(x);
_it=_set.end();
_it--;
int l,r;
if(it==_set.begin())l=*(_it);
else
{
it--;l=*it;it++;
}
it++;
if(it==_set.end())r=*(_set.begin());
else r=*it;
ans+=getRoad(l,r);ans-=getRoad(l,x);ans-=getRoad(x,r);
}
_set.erase(x);
}
}
}
//finish=clock();
//printf("%.3lf\n",(finish-start)/CLOCKS_PER_SEC);
return 0;
}