HDU 2586 How far away?

http://acm.hdu.edu.cn/showproblem.php?pid=2586

题意:给定一个图,有M个询问。每一次询问为询问u,v两个点的距离为多少?

题解:LCA问题。

  1 #include <iostream>
  2 #include <cstring>
  3 #include <cstdio>
  4 #include <cstdlib>
  5 #include <cmath>
  6 #include <string>
  7 #include <vector>
  8 #include <list>
  9 #include <map>
 10 #include <queue>
 11 #include <stack>
 12 #include <bitset>
 13 #include <algorithm>
 14 #include <numeric>
 15 #include <functional>
 16 #include <set>
 17 #include <fstream>
 18
 19 using namespace std;
 20
 21 const int maxn=40010;
 22
 23 struct edge{
 24     int from,to,cost,next;
 25 };
 26 edge es[maxn*2];
 27 int head[maxn],idx;
 28 int dis[maxn],N,M;
 29 int U[maxn],V[maxn];
 30 int par[maxn],rankh[maxn];
 31 int LCA[maxn];
 32 bool used[maxn];
 33
 34 void add_edge(int u,int v,int cost)
 35 {
 36     es[idx].from=u;
 37     es[idx].to=v;
 38     es[idx].cost=cost;
 39     es[idx].next=head[u];
 40     head[u]=idx++;
 41 }
 42
 43 void build_graph(int u,int v,int cost)
 44 {
 45     add_edge(u,v,cost);
 46     add_edge(v,u,cost);
 47 }
 48
 49 void init(int n)
 50 {
 51     for(int i=0;i<=n;i++)
 52     {
 53         par[i]=i;
 54         rankh[i]=0;
 55     }
 56 }
 57
 58 int find(int x)
 59 {
 60     if(x==par[x]) return x;
 61     else return par[x]=find(par[x]);
 62 }
 63
 64 void tarjan(int u)
 65 {
 66     used[u]=true;
 67     for(int  i=0;i<M;i++)
 68     {
 69         if(U[i]==u&&used[V[i]]) LCA[i]=find(V[i]);
 70         if(V[i]==u&&used[U[i]]) LCA[i]=find(U[i]);
 71     }
 72     for(int i=head[u];i!=-1;i=es[i].next)
 73     {
 74         int v=es[i].to;
 75         if(!used[v]){
 76             dis[v]=dis[u]+es[i].cost;
 77             tarjan(v);
 78             par[v]=u;
 79         }
 80     }
 81 }
 82
 83 int main()
 84 {
 85 //    freopen("/Users/apple/Desktop/暑假/HDU 2586/HDU 2586/in","r",stdin);
 86     int T;
 87     scanf("%d",&T);
 88     while(T--)
 89     {
 90         scanf("%d%d",&N,&M);
 91         init(2*N);
 92         memset(head,-1,sizeof(head));
 93         idx=0;
 94         memset(used,false,sizeof(used));
 95         dis[1]=0;
 96         for(int i=0;i<=N;i++)
 97         {
 98             U[i]=V[i]=LCA[i]=0;
 99         }
100         for(int i=0;i<N-1;i++)
101         {
102             int u,v,cost;
103             scanf("%d%d%d",&u,&v,&cost);
104             build_graph(u, v, cost);
105         }
106         for(int i=0;i<M;i++)
107         {
108             int u,v;
109             scanf("%d%d",&u,&v);
110             U[i]=u,V[i]=v;
111         }
112         tarjan(1);
113         for(int i=0;i<M;i++)
114         {
115             int res=dis[U[i]]+dis[V[i]]-2*dis[LCA[i]];
116             printf("%d\n",res);
117         }
118     }
119     return 0;
120 }
时间: 2024-10-27 02:47:23

HDU 2586 How far away?的相关文章

LCA(最近公共祖先)--tarjan离线算法 hdu 2586

HDU 2586 How far away ? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 11320    Accepted Submission(s): 4119 Problem Description There are n houses in the village and some bidirectional roads c

HDU - 2586 - How far away ?

先上题目: How far away ? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 4936    Accepted Submission(s): 1866 Problem Description There are n houses in the village and some bidirectional roads conne

HDU 2586 How far away ? (LCA最近公共祖先)

题目地址:HDU 2586 LCA第一发. 纯模板题. 偷懒用的vector,结果一直爆栈.把G++改成C++就过了.. 代码如下: #include <iostream> #include <string.h> #include <math.h> #include <queue> #include <algorithm> #include <stdlib.h> #include <map> #include <se

HDU 2586 + HDU 4912 最近公共祖先

先给个LCA模板 HDU 1330(LCA模板) #include <cstdio> #include <cstring> #define N 40005 struct Edge{ int x,y,d,ne; }; Edge e[N*2],e2[N*2]; int be[N],be2[N],all,all2,n,m; bool vis[N]; int fa[N]; int ancestor[N][3]; int dis[N]; void add(int x, int y, int

hdu 2586 LCA模板题(离线算法)

http://acm.hdu.edu.cn/showproblem.php?pid=2586 Problem Description There are n houses in the village and some bidirectional roads connecting them. Every day peole always like to ask like this "How far is it if I want to go from house A to house B&quo

最近公共祖先(lca) hdu 2586

hdu 2586 How far away ? 题目大意:给定n-1条边构成一棵树,无向的:和m个询问,对于每一个询问按顺序回答. 结题思路:lca算法算出最近公共祖先,然后dis[u]+dis[v]-2*dis[father](father是u,v的最近公共祖先),小trick是在构造询问树的时候把权值设成询问对应的输入顺序 #include <iostream> #include <cstdio> #include <cstring> #include <al

HDU 2586 LCA-Tarjan

还是LCA-tarjan算法,跟POJ 1330做法基本类似,只是这个题目要求输出两个点的最短距离,其实利用LCA的性质,就是 两个点分别到最近公共祖先的距离之和 一开始本来想用并查集把路径长度给找出来,但是不太好处理,原因是我刚好找到的这个点还没有加入到并查集中,(因为还没回溯上去),如果马上就合并,我还得把父亲传下来,还破坏了原有算法的结构(在孩子这里就进行了并查集合并操作),会产生奇怪的结果... 有个很简便又机智的方法,就是在dfs的过程中 一边记录从rt到下面的点的距离dis,假设 A

hdu 2586 How far away ?倍增LCA

hdu 2586 How far away ?倍增LCA 题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=2586 思路: 针对询问次数多的时候,采取倍增求取LCA,同时跟新距离数组 因为 \(2^{16} > 40000\) 所以所以表示祖先的数组dp[][]第二维取到16即可 就这道题来说,与比较tarjan比较,稍快一点 代码: #include <iostream> #include <algorithm> #includ

HDU 2586 LCA模板题

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2586 题目大意:在一个无向树上,求一条链权和. 解题思路: 0 | 1 /   \ 2      3 设dist[i]为i到根0的链和,求法(Dfs过程中dist[v]=dist[u]+e[i].w) 对于树中任意两点形成的链,可以通过LCA最近公共祖先剖分. 比如2->3,就可以经过LCA点1:  2->1->3 链和=dist[u]+dist[v]-2*dist[LCA[u,v]] (