标签:
| 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