标签:
You are given a tree (an undirected acyclic connected graph) with N nodes, and edges numbered 1, 2, 3...N-1. Each edge has an integer value assigned to it, representing its length.
We will ask you to perfrom some instructions of the following form:
Example:
N = 6
1 2 1 // edge connects node 1 and node 2 has cost 1
2 4 1
2 5 2
1 3 1
3 6 2
Path from node 4 to node 6 is 4 -> 2 -> 1 -> 3 -> 6
DIST 4 6 : answer is 5 (1 + 1 + 1 + 2 = 5)
KTH 4 6 4 : answer is 3 (the 4-th node on the path from node 4 to node 6 is 3)
The first line of input contains an integer t, the number of test cases (t <= 25). t test cases follow.
For each test case:
There is one blank line between successive tests.
For each "DIST" or "KTH" operation, write one integer representing its result.
Print one blank line after each test.
Input: 1 6 1 2 1 2 4 1 2 5 2 1 3 1 3 6 2 DIST 4 6 KTH 4 6 4 DONE Output: 53
题目大意:DIST 4 6询问4 到6的距离,KTH 4 6 4,询问4 到6经过的第4个点
ac代码
#include<stdio.h> #include<string.h> #include<stdlib.h> #include<queue> #include<iostream> #define MAXN 10010 using namespace std; int head[10010],cnt,vis[10010]; struct s { int u,v,w,next; }edge[10010<<1]; struct LCT { int bef[10010],pre[10010],next[10010][2],key[10010],sum[10010],belong[10010],num[10010]; void init() { memset(pre,0,sizeof(pre)); memset(next,0,sizeof(next)); } void pushup(int x) { sum[x]=key[x]+sum[next[x][1]]+sum[next[x][0]]; num[x]=num[next[x][1]]+num[next[x][0]]+1; } void rotate(int x,int kind) { int y,z; y=pre[x]; z=pre[y]; next[y][!kind]=next[x][kind]; pre[next[x][kind]]=y; next[z][next[z][1]==y]=x; pre[x]=z; next[x][kind]=y; pre[y]=x; pushup(y); } void splay(int x) { int rt; for(rt=x;pre[rt];rt=pre[rt]); if(x!=rt) { bef[x]=bef[rt]; bef[rt]=0; while(pre[x]) { if(next[pre[x]][0]==x) { rotate(x,1); } else rotate(x,0); } pushup(x); } } void access(int x) { int fa; for(fa=0;x;x=bef[x]) { splay(x); pre[next[x][1]]=0; bef[next[x][1]]=x; next[x][1]=fa; pre[fa]=x; bef[fa]=0; fa=x; pushup(x); } } int query(int x,int y) { access(y); for(y=0;x;x=bef[x]) { splay(x); if(!bef[x]) return sum[y]+sum[next[x][1]]; pre[next[x][1]]=0; bef[next[x][1]]=x; next[x][1]=y; pre[y]=x; bef[y]=0; y=x; pushup(x); } } int select(int x,int k) { while(num[next[x][0]]+1!=k) { if(num[next[x][0]]+1>k) x=next[x][0]; else { k-=num[next[x][0]]+1; x=next[x][1]; } } return x; } int KTH(int y,int x,int k) { access(y); for(y=0;x;x=bef[x]) { splay(x); if(!bef[x]) { if(num[next[x][1]]+1==k) return x; else if(num[next[x][1]]+1>k) return select(next[x][1],num[next[x][1]]-k+1); return select(y,k-num[next[x][1]]-1); } pre[next[x][1]]=0; bef[next[x][1]]=x; next[x][1]=y; pre[y]=x; bef[y]=0; y=x; pushup(x); } } }lct; void add(int u,int v,int w) { edge[cnt].u=u; edge[cnt].v=v; edge[cnt].w=w; edge[cnt].next=head[u]; head[u]=cnt++; } void bfs(int u) { int i,y; queue<int>q; memset(vis,0,sizeof(vis)); vis[u]=1; q.push(u); while(!q.empty()) { u=q.front(); q.pop(); for(int i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].v; if(!vis[v]) { lct.bef[v]=u; lct.key[v]=lct.sum[v]=edge[i].w; vis[v]=1; q.push(v); } } } } int main() { int t; scanf("%d",&t); while(t--) { int n,i; scanf("%d",&n); cnt=0; memset(head,-1,sizeof(head)); for(i=1;i<n;i++) { int u,v,w; scanf("%d%d%d",&u,&v,&w); add(u,v,w); add(v,u,w); } lct.init(); bfs(1); char op[10]; while(scanf("%s",op)!=EOF) { if(!strcmp(op,"DONE")) break; if(op[0]=='D') { int x,y; scanf("%d%d",&x,&y); printf("%d\n",lct.query(x,y)); } else { int x,y,z; scanf("%d%d%d",&x,&y,&z); printf("%d\n",lct.KTH(x,y,z)); } } } }
版权声明:本文为博主原创文章,未经博主允许不得转载。
SPOJ 题目913QTREE2 - Query on a tree II(Link Cut Tree 查询路径第k个点)
标签:
原文地址:http://blog.csdn.net/yu_ch_sh/article/details/48016815