hdu2586 How far away

来源:互联网 发布:网络打印机打印错误 编辑:程序博客网 时间:2024/05/01 18:55

题目都翻译过了,只需用脑整理词序......

【题目描述】:

有N个房子在村里和一些双向道路连接。每一天,人们总是喜欢这样问“有多远,如果我想从房子到房子B”?通常很难回答。但幸运的是,在这个村的回答永远是独一无二的,由于道路建成的方式,这是一个独特的简单路径(“简单”意味着你不能访问一个地方两次)每两个房子之间。你的任务是回答这些好奇的人。

【输入】:

第一行是一个整数T(t<=10),表示测试用例的数目。
对于每个测试用例,在第一行有2个数n(2<=n<=40000)和M(1<=M<=200),房屋的数量和查询的数量。下面的n-1条线路每组三个数即,i,j,k分离不单空间,这意味着有一条连接房子房子我和J,长度为k(0<k<=40000)。房屋标记从1到n。
接下来的m行各有不同的整数i和j,你要回答我的房子i和房子J之间的距离

【输出】:

对于每一个测试案例,输出M行。每一行代表该查询的答案。输出一个平淡无奇的线每一个测试案例后。

【样例输入】:

23 21 2 103 1 151 22 32 21 2 1001 22 1
【样例输出】:

1025100100

题解Here!

此题为一道LCA问题,基本上可以算模板题。先找到询问两点(假设为u,v)的最近公共祖先,再计算距离。

距离:用dis[]记下根节点到任意节点的距离,则ans=dis[u]+dis[v]-2*dis[lca(u, v)];

上代码:

#include<iostream>#include<algorithm>#include<stdio.h>#include<string.h>#define MAXN 40010#define MAXM 205using namespace std;typedef struct Node{       int v,d;       Node *next;}node;node *linka[MAXN],a[MAXN<<1],*linkb[MAXN],b[MAXN<<1];int idx1,idx2,n,m;int fa[MAXN],vis[MAXN],dis[MAXN],s[MAXM][3];int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}inline int read(){       int date=0,w=1;char c=0;       while(c!='-'&&(c<'0'||c>'9'))c=getchar();       if(c=='-'){w=-1;c=getchar();}       while(c>='0'&&c<='9'){date=date*10+c-'0';c=getchar();}       return date*w;}void add(int u,int v,int d,node c[],node *linkc[],int &idx){     c[idx].v=v;     c[idx].d=d;     c[idx].next=linkc[u];     linkc[u]=c+idx++;     c[idx].v=u;     c[idx].d=d;     c[idx].next=linkc[v];     linkc[v]=c+idx++;}void LCA(int u){     vis[u]=1;     fa[u]=u;     for(node *p=linkb[u];p;p=p->next)     if(vis[p->v])     s[p->d][2]=find(p->v);     for(node *p=linka[u];p;p=p->next)     if(!vis[p->v]){                   dis[p->v]=dis[u]+p->d;                   LCA(p->v);                   fa[p->v]=u;                   }}int main(){    int t,i,u,v,d;    t=read();    while(t--){               n=read();m=read();               idx1=idx2=0;               memset(linka,0,sizeof(linka));               memset(linkb,0,sizeof(linkb));               for(i=1;i<=n;i++){                                 u=read();v=read();d=read();                                 add(u,v,d,a,linka,idx1);                                 }               for(i=1;i<=m;i++){                                 u=read();v=read();                                 add(u,v,i,b,linkb,idx2);                                 s[i][0]=u;                                 s[i][1]=v;                                 }               memset(vis,0,sizeof(vis));               dis[1]=0;               LCA(1);               for(i=1;i<=m;i++)               printf("%d\n",dis[s[i][0]]+dis[s[i][1]]-2*dis[s[i][2]]);               }    return 0;}


原创粉丝点击