计算树上的路径长度。input要去查poj 1984。

任意建一棵树,利用树形结构,将问题转化为u,v,lca(u,v)三个点到根的距离。输出d[u]+d[v]-2*d[lca(u,v)]。

倍增求解:

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<queue>
  4. #include<algorithm>
  5. #define rep(i,a,b) for(int i=a;i<=b;i++)
  6. #define clr(a,m) memset(a,m,sizeof(a))
  7. using namespace std;
  8.  
  9. const int MAXN=;
  10. const int POW = ;
  11.  
  12. struct Edge{
  13. int v,next,c;
  14. Edge(){}
  15. Edge(int _v,int _c,int _next):v(_v),c(_c),next(_next){}
  16. }edge[MAXN<<];
  17.  
  18. int head[MAXN],tol;
  19. int p[MAXN][POW],d[MAXN];
  20. int vis[MAXN],dis[MAXN];
  21. queue<int>q;
  22.  
  23. void init()
  24. {
  25. tol=;
  26. clr(head,-);
  27. }
  28.  
  29. void add(int u,int v,int c)
  30. {
  31. edge[tol]=Edge(v,c,head[u]);
  32. head[u]=tol++;
  33. }
  34.  
  35. void bfs(int x)
  36. {
  37. clr(vis,);
  38. clr(dis,);
  39. while(!q.empty())
  40. q.pop();
  41. q.push(x);
  42. vis[x]=;
  43. dis[x]=;
  44. while(!q.empty())
  45. {
  46. int u=q.front();
  47. q.pop();
  48. for(int i=head[u];i!=-;i=edge[i].next)
  49. {
  50. int v=edge[i].v;
  51. if(vis[v])
  52. continue;
  53. q.push(v);
  54. vis[v]=;
  55. dis[v]=dis[u]+edge[i].c;
  56. }
  57. }
  58. }
  59.  
  60. void dfs(int u,int fa){
  61. d[u]=d[fa]+;
  62. p[u][]=fa;
  63. for(int i=;i<POW;i++) p[u][i]=p[p[u][i-]][i-];
  64. for(int i=head[u];i!=-;i=edge[i].next){
  65. int v=edge[i].v;
  66. if(v==fa) continue;
  67. dfs(v,u);
  68. }
  69. }
  70.  
  71. int lca( int a, int b ){
  72. if( d[a] > d[b] ) a ^= b, b ^= a, a ^= b;
  73. if( d[a] < d[b] ){
  74. int del = d[b] - d[a];
  75. for( int i = ; i < POW; i++ ) if(del&(<<i)) b=p[b][i];
  76. }
  77. if( a != b ){
  78. for( int i = POW-; i >= ; i-- )
  79. if( p[a][i] != p[b][i] )
  80. a = p[a][i] , b = p[b][i];
  81. a = p[a][], b = p[b][];
  82. }
  83. return a;
  84. }
  85.  
  86. void LCA(int n)
  87. {
  88. clr(p,);
  89. d[]=;
  90. dfs(,);
  91.  
  92. bfs();
  93.  
  94. int k;
  95. scanf("%d",&k);
  96. int u,v;
  97. rep(i,,k){
  98. scanf("%d%d",&u,&v);
  99. printf("%d\n",dis[u]+dis[v]-*dis[lca(u,v)]);
  100. }
  101. }
  102.  
  103. int main()
  104. {
  105. int n,m;
  106. scanf("%d%d",&n,&m);
  107. init();
  108. rep(i,,m){
  109. int u,v,c;
  110. scanf("%d%d%d%*s",&u,&v,&c);
  111. add(u,v,c);
  112. add(v,u,c);
  113. }
  114.  
  115. LCA(n);
  116. return ;
  117. }

又用tarjin离线做了一遍= =

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<queue>
  4. #include<algorithm>
  5. #define rep(i,a,b) for(int i=a;i<=b;i++)
  6. #define clr(a,m) memset(a,m,sizeof(a))
  7. using namespace std;
  8.  
  9. const int MAXN=;
  10.  
  11. struct Edge{
  12. int v,next,c;
  13. Edge(){}
  14. Edge(int _v,int _c,int _next):v(_v),c(_c),next(_next){}
  15. }edge[MAXN<<];
  16.  
  17. struct EDGE{
  18. int u,v;
  19. int ans;
  20. EDGE(){}
  21. EDGE(int _u,int _v):u(_u),v(_v),ans(-){}
  22. };
  23.  
  24. int head[MAXN],tol;
  25. int p[MAXN],vis[MAXN],dis[MAXN];
  26.  
  27. queue<int>q;
  28. vector<int>query[MAXN];
  29. vector<EDGE>G;
  30.  
  31. void init()
  32. {
  33. tol=;
  34. clr(head,-);
  35. }
  36.  
  37. void add(int u,int v,int c)
  38. {
  39. edge[tol]=Edge(v,c,head[u]);
  40. head[u]=tol++;
  41. }
  42.  
  43. void build(int m)
  44. {
  45. init();
  46. rep(i,,m){
  47. int u,v,c;
  48. scanf("%d%d%d%*s",&u,&v,&c);
  49. add(u,v,c);
  50. add(v,u,c);
  51. }
  52.  
  53. int k;
  54. scanf("%d",&k);
  55. rep(i,,k){
  56. int u,v,siz;
  57. scanf("%d%d",&u,&v);
  58.  
  59. G.push_back(EDGE(u,v));
  60. siz=G.size();
  61. query[u].push_back(siz-);
  62.  
  63. G.push_back(EDGE(v,u));
  64. siz=G.size();
  65. query[v].push_back(siz-);
  66. }
  67. }
  68.  
  69. void bfs(int x)
  70. {
  71. clr(vis,);
  72. clr(dis,);
  73. while(!q.empty())
  74. q.pop();
  75. q.push(x);
  76. vis[x]=;
  77. dis[x]=;
  78. while(!q.empty())
  79. {
  80. int u=q.front();
  81. q.pop();
  82. for(int i=head[u];i!=-;i=edge[i].next)
  83. {
  84. int v=edge[i].v;
  85. if(vis[v])
  86. continue;
  87. q.push(v);
  88. vis[v]=;
  89. dis[v]=dis[u]+edge[i].c;
  90. }
  91. }
  92. }
  93.  
  94. int find(int x)
  95. {
  96. return (x==p[x])?x:(p[x]=find(p[x]));
  97. }
  98.  
  99. void dfs(int x)
  100. {
  101. vis[x]=;
  102. for(int i=head[x];i!=-;i=edge[i].next)
  103. {
  104. int v=edge[i].v;
  105. if(vis[v])
  106. continue;
  107. dfs(v);
  108. p[v]=x;
  109. }
  110.  
  111. int siz =query[x].size()-;
  112. rep(i,,siz)
  113. {
  114. int t=query[x][i];
  115. if(vis[G[t].v]){
  116. G[t].ans=find(G[t].v);
  117. }
  118. }
  119. }
  120.  
  121. void LCA(int rt,int n)
  122. {
  123. clr(vis,);
  124. rep(i,,n)
  125. p[i]=i;
  126. dfs(rt);
  127. }
  128.  
  129. void PRT()
  130. {
  131. int siz=G.size();
  132. for(int i=;i<siz;i+=)
  133. {
  134. int u=G[i].u;
  135. int v=G[i].v;
  136. if(G[i].ans!=-)
  137. printf("%d\n",dis[u]+dis[v]-*dis[G[i].ans]);
  138. else
  139. printf("%d\n",dis[u]+dis[v]-*dis[G[i^].ans]);
  140. }
  141. }
  142.  
  143. int main()
  144. {
  145. int n,m;
  146. scanf("%d%d",&n,&m);
  147. build(m);
  148. bfs();
  149. LCA(,n);
  150. PRT();
  151. return ;
  152. }

poj 1986 Distance Queries(LCA:倍增/离线)的更多相关文章

  1. POJ.1986 Distance Queries ( LCA 倍增 )

    POJ.1986 Distance Queries ( LCA 倍增 ) 题意分析 给出一个N个点,M条边的信息(u,v,w),表示树上u-v有一条边,边权为w,接下来有k个询问,每个询问为(a,b) ...

  2. POJ 1986 Distance Queries LCA两点距离树

    标题来源:POJ 1986 Distance Queries 意甲冠军:给你一棵树 q第二次查询 每次你问两个点之间的距离 思路:对于2点 u v dis(u,v) = dis(root,u) + d ...

  3. POJ 1986 Distance Queries(Tarjan离线法求LCA)

    Distance Queries Time Limit: 2000MS   Memory Limit: 30000K Total Submissions: 12846   Accepted: 4552 ...

  4. poj 1986 Distance Queries LCA

    题目链接:http://poj.org/problem?id=1986 Farmer John's cows refused to run in his marathon since he chose ...

  5. POJ 1986 - Distance Queries - [LCA模板题][Tarjan-LCA算法]

    题目链接:http://poj.org/problem?id=1986 Description Farmer John's cows refused to run in his marathon si ...

  6. POJ 1986 Distance Queries(LCA Tarjan法)

    Distance Queries [题目链接]Distance Queries [题目类型]LCA Tarjan法 &题意: 输入n和m,表示n个点m条边,下面m行是边的信息,两端点和权,后面 ...

  7. POJ 1986 Distance Queries / UESTC 256 Distance Queries / CJOJ 1129 【USACO】距离咨询(最近公共祖先)

    POJ 1986 Distance Queries / UESTC 256 Distance Queries / CJOJ 1129 [USACO]距离咨询(最近公共祖先) Description F ...

  8. POJ 1986 Distance Queries 【输入YY && LCA(Tarjan离线)】

    任意门:http://poj.org/problem?id=1986 Distance Queries Time Limit: 2000MS   Memory Limit: 30000K Total ...

  9. poj 1986 Distance Queries(LCA)

    Description Farmer John's cows refused to run in his marathon since he chose a path much too long fo ...

  10. poj 1986 Distance Queries 带权lca 模版题

    Distance Queries   Description Farmer John's cows refused to run in his marathon since he chose a pa ...

随机推荐

  1. mysql Host ‘XXXXXX’ is blocked because of many connection errors

    mysql Host ‘XXXXXX’ is blocked because of many connection errors ERROR 1129 (00000): Host ‘XXXXXX’ i ...

  2. 使用静态变量的方法求n!

    下面的程序可以输出1-5的阶乘值,如果需要把5改为n,则可求出1-n的阶乘值. void main() { setvbuf(stdout,NULL,_IONBF,); int fac(int n); ...

  3. Filter及FilterChain的使用详解(转)

    一.Filter的介绍及使用 什么是过滤器? 与Servlet相似,过滤器是一些web应用程序组件,可以绑定到一个web应用程序中.但是与其他web应用程序组件不同的是,过滤器是"链&quo ...

  4. java Socket用法详解(转)

    在客户/服务器通信模式中, 客户端需要主动创建与服务器连接的 Socket(套接字), 服务器端收到了客户端的连接请求, 也会创建与客户连接的 Socket. Socket可看做是通信连接两端的收发器 ...

  5. hdu 2196

    树形dp 本文出自   http://blog.csdn.net/shuangde800 题目传送门 题意: 给出一棵树,求离每个节点最远的点的距离 思路: 把无根树转化成有根树分析, 对于上面那棵树 ...

  6. Web App之一

    JSP/HTML/CSS---------View(不包含任何的数据,只作为基本的layout) JS------------------------Data(update JSP/HTML)

  7. object-c 入门基础篇

    原地址:http://www.cnblogs.com/moonvan/archive/2011/10/13/2210498.html 一.Objective-C与C的渊源 Objective-C诞生于 ...

  8. Chp11: Sorting and Searching

    Common Sorting Algo: Bubble Sort: Runime: O(n2) average and worst case. Memory: O(1). void BubbleSor ...

  9. POJ 1666

    #include<iostream> using namespace std; int main() { int num_stu; int i; ; do{ time=; cin>& ...

  10. autocomplete参数说明以及实例

    JQuery autocomplete使用手册 Jquery autocomplete是一个很强大的类似google suggest的自动提示插件.它几乎可以满足我们所有的需要. 官方网站:http: ...