您的位置:首页 > 产品设计 > UI/UE

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个数

#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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: