标签:
| Time Limit: 2000MS | Memory Limit: 30000K | |
| Total Submissions: 10142 | Accepted: 3575 | |
| Case Time Limit: 1000MS | ||
Description
Input
Output
Sample Input
7 6 1 6 13 E 6 3 9 E 3 5 7 S 4 1 3 N 2 4 20 W 4 7 2 S 3 1 6 1 4 2 6
Sample Output
13 3 36
Hint
Source
求树上两个点最近距离
ac代码
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct s
{
int u,v,w,next;
}edge[100100];
struct que
{
int u,v,num,next;
}q[100010];
int head1[100100],head2[100010],cnt1,cnt2,dis[100100],pre[100100],n,m,qq,vis[100100],ans[100100 ];
int find(int x)
{
if(x==pre[x])
return x;
return find(pre[x]);
}
void init()
{
memset(head1,-1,sizeof(head1));
memset(head2,-1,sizeof(head2));
memset(dis,0,sizeof(dis));
memset(vis,0,sizeof(vis));
cnt1=cnt2=0;
}
void add1(int u,int v,int w)
{
edge[cnt1].u=u;
edge[cnt1].v=v;
edge[cnt1].w=w;
edge[cnt1].next=head1[u];
head1[u]=cnt1++;
}
void add2(int u,int v,int i)
{
q[cnt2].u=u;
q[cnt2].v=v;
q[cnt2].num=i;
q[cnt2].next=head2[u];
head2[u]=cnt2++;
}
void tarjan(int u,int len)
{
int i,v;
pre[u]=u;
dis[u]=len;
vis[u]=1;
for(i=head2[u];i!=-1;i=q[i].next)
{
if(vis[q[i].v])
ans[q[i].num]=dis[u]+dis[q[i].v]-2*dis[find(q[i].v)];
}
for(i=head1[u];i!=-1;i=edge[i].next)
{
v=edge[i].v;
if(!vis[v])
{
tarjan(v,len+edge[i].w);
pre[v]=u;
}
}
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
init();
while(m--)
{
int a,b,c;
char str[2];
scanf("%d%d%d%s",&a,&b,&c,str);
add1(a,b,c);
add1(b,a,c);
}
scanf("%d",&qq);
int i;
for(i=1;i<=qq;i++)
{
int a,b;
scanf("%d%d",&a,&b);
add2(a,b,i);
add2(b,a,i);
}
tarjan(1,0);
// int i;
for(i=1;i<=qq;i++)
{
printf("%d\n",ans[i]);
}
}
}
POJ 题目1986 Distance Queries(LCA 离线)
标签:
原文地址:http://blog.csdn.net/yu_ch_sh/article/details/45973111