spoj 913 Query on a tree II 倍增
2012-03-04 09:00
399 查看
题意:给定一棵边带权树
定义两种询问
DIST a b : a b之间距离
KTH a b k : a b之间的路径的第k个数
定义两种询问
DIST a b : a b之间距离
KTH a b k : a b之间的路径的第k个数
#include<iostream> #include<cstring> #include<cmath> #include<cstdio> using namespace std; #define MAXN 10010 struct node { int num,weight; node *next; }; node *graph[MAXN]; node memo[2*MAXN]; int euler[2*MAXN],father[MAXN][20],d[MAXN],home[MAXN],Log[2*MAXN],length[MAXN]; int sparse_table[2*MAXN][20],sparse_table_num[2*MAXN][20]; int n,top; void my_log() { Log[1]=0; for(int i=2;i<2*MAXN;i++) Log[i]=Log[i/2]+1; } void add(int x,int y,int z) { node *p=&memo[top++]; p->num=y; p->weight=z; p->next=graph[x]; graph[x]=p; p=&memo[top++]; p->num=x; p->weight=z; p->next=graph[y]; graph[y]=p; } void dfs(int i,int deep,int fa,int w) { euler[++top]=i; home[i]=top; d[i]=deep; father[i][0]=fa; length[i]=length[fa]+w; for(int j=1;(1<<j)<d[i];j++) { father[i][j]=father[father[i][j-1]][j-1]; } for(node *p=graph[i];p;p=p->next) if(p->num!=father[i][0]) { dfs(p->num,deep+1,i,p->weight); euler[++top]=i; } } void build_sparse_table() { int i,j; for(i=1;i<=top;i++) { sparse_table[i][0]=d[euler[i]]; sparse_table_num[i][0]=euler[i]; } for(j=1;(1<<j)<=top;j++) { for(i=1;i<=top-(1<<j)+1;i++) { if(sparse_table[i][j-1]<sparse_table[i+(1<<(j-1))][j-1]) { sparse_table[i][j]=sparse_table[i][j-1]; sparse_table_num[i][j]=sparse_table_num[i][j-1]; } else { sparse_table[i][j]=sparse_table[i+(1<<(j-1))][j-1]; sparse_table_num[i][j]=sparse_table_num[i+(1<<(j-1))][j-1]; } } } } int LCA(int x,int y) { if(x>y) { int t; t=x; x=y; y=t; } int z=Log[y-x+1]; if(sparse_table[x][z]<sparse_table[y-(1<<z)+1][z]) return sparse_table_num[x][z]; else return sparse_table_num[y-(1<<z)+1][z]; } int find(int x,int l) { int i=0; while(l>0) { if(l&1) x=father[x][i]; i++; l>>=1; } return x; } void solve() { char c[10]; int x,y,z; int temp; while(1) { scanf("%s",c); if(c[0]=='D'&&c[1]=='O') break; if(c[0]=='D') { scanf("%d%d",&x,&y); temp=length[x]+length[y]-2*length[LCA(home[x],home[y])]; printf("%d\n",temp); } else { scanf("%d%d%d",&x,&y,&z); int fa=LCA(home[x],home[y]); if(d[x]-d[fa]==z-1) { printf("%d\n",fa); } else if(d[x]-d[fa]>z-1) { printf("%d\n",find(x,z-1)); } else printf("%d\n",find(y,d[x]+d[y]-2*d[fa]-z+1)); } } printf("\n"); } int main() { int T,i; int x,y,z; my_log(); scanf("%d",&T); while(T--) { top=0; memset(graph,0,sizeof(graph)); memset(father,0xff,sizeof(father)); memset(length,0,sizeof(length)); scanf("%d",&n); for(i=1;i<n;i++) { scanf("%d%d%d",&x,&y,&z); add(x,y,z); } top=0; length[1]=0; dfs(1,1,0,0); /*for(i=1;i<=n;i++) for(int j=0;j<=2;j++) { printf("%d %d %d %d\n",i,j,father[i][j],d[father[i][j]]); }*/ build_sparse_table(); solve(); } return 0; }
相关文章推荐
- spoj 913 Query on a tree II (倍增lca)
- SPOJ 913 Query on a tree II ( 树链剖分 + 倍增 )
- SPOJ 913 QTREE系列- Query on a tree II (倍增LCA)
- SPOJ913 Query on a tree II
- SPOJ Query on a tree II (倍增LCA)
- SPOJ 913 Query on a tree II(动态树)
- 【SPOJ】913 Query on a tree II
- 【SPOJ】913 Query on a tree II QTREE系列之2【LCA】
- SPOJ Query on a tree II (树剖||倍增LCA)(占位)
- SPOJ 913 Query on a tree II 树链剖分
- SPOJ Query on a tree II (倍增LCA)
- SPOJ 913 Query on a tree II
- SPOJ Query on a tree II
- SPOJ QTREE2 Query on a tree II 倍增lca
- SPOJ QTREE2 Query on a tree II(lct)
- SPOJ 题目913QTREE2 - Query on a tree II(Link Cut Tree 查询路径第k个点)
- LCA SP913 QTREE2 - Query on a tree II
- Spoj Query on a tree II (LCA)
- 【SPOJ QTREE2】QTREE2 - Query on a tree II(LCA)
- 【spoj】【QTREE2 - Query on a tree II】