[zoj3195]Design the city(LCA)

解题关键:求树上三点间的最短距离。

解题关键:$ans = (dis(a,b) + dis(a,c) + dis(b,c))/2$

  1 //#pragma comment(linker, "/STACK:1024000000,1024000000")
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<cstdlib>
  6 #include<cmath>
  7 #include<iostream>
  8 typedef long long ll;
  9 using namespace std;
 10 const int maxn=51000;
 11 const int maxm=30;
 12 int _pow[maxm],m,n;
 13 int head[maxn],tot;
 14 int ver[maxn*2],depth[maxn*2],first[maxn],rmq[maxn*2][25],id;//5个数组,注意哪个需要乘2
 15 int dis[maxn];
 16 inline int read(){
 17     char k=0;char ls;ls=getchar();for(;ls<‘0‘||ls>‘9‘;k=ls,ls=getchar());
 18     int x=0;for(;ls>=‘0‘&&ls<=‘9‘;ls=getchar())x=(x<<3)+(x<<1)+ls-‘0‘;
 19     if(k==‘-‘)x=0-x;return x;
 20 }
 21
 22 struct edge{
 23     int to,w,nxt;
 24 }e[maxn*2];//链式前向星建树
 25
 26 void init(){
 27     memset(head,-1,sizeof head);
 28     tot=0;
 29     id=0;
 30 }
 31
 32 void add_edge(int u,int v,int w){
 33     e[tot].to=v;
 34     e[tot].w=w;
 35     e[tot].nxt=head[u];
 36     head[u]=tot++;
 37 }
 38
 39 void dfs(int u,int fa,int dep){
 40     ver[++id]=u;//第i个访问到的结点编号
 41     depth[id]=dep;//第i个访问到的结点深度
 42     first[u]=id;
 43     for(int i=head[u];i!=-1;i=e[i].nxt){
 44         int v=e[i].to;
 45         int w=e[i].w;
 46         if(v==fa) continue;
 47         dis[v]=dis[u]+w;//dis是先序遍历求
 48         dfs(v,u,dep+1);
 49         ver[++id]=u;//后序遍历,再次访问父节点
 50         depth[id]=dep;
 51     }
 52 }
 53
 54 void rmq_init(int n){
 55     int k=int(log(n)/log(2));
 56     for(int i=1;i<=n;++i)    rmq[i][0]=i;
 57     for(int j=1;j<=k;++j){
 58         for(int i=1;i+_pow[j]-1<=n;++i){//因为存的是索引
 59             int a=rmq[i][j-1],b=rmq[i+_pow[j-1]][j-1];
 60             rmq[i][j]=depth[a]<depth[b]?a:b;
 61         }
 62     }
 63 }
 64
 65 int rmq_query(int l,int r){
 66     int k=int(log(r-l+1.0)/log(2.0));
 67     int a=rmq[l][k],b=rmq[r-_pow[k]+1][k];
 68     return depth[a]<depth[b]?a:b;
 69 }//返回的依然是索引
 70
 71 int LCA(int u,int v){
 72     int x=first[u],y=first[v];
 73     if(x>y)swap(x,y);
 74     int res=rmq_query(x,y);
 75     return ver[res];
 76 }
 77
 78 int main(){
 79     for(int i=0;i<maxm;++i)    _pow[i]=1<<i; //预处理2^n
 80     int t,a,b,c,d,x=0;
 81     while(scanf("%d",&n)!=EOF){
 82         if(x++) printf("\n");
 83         init();
 84         for(int i=0;i<n-1;++i){
 85             a=read()+1,b=read()+1,c=read();
 86             add_edge(a,b,c);
 87             add_edge(b,a,c);
 88         }
 89         dfs(1,-1,0);
 90         rmq_init(2*n-1);
 91         d=read();
 92         for(int i=0;i<d;++i){
 93             a=read()+1;b=read()+1;c=read()+1;
 94             int t1=LCA(a,b);t1=dis[a]+dis[b]-2*dis[t1];
 95             int t2=LCA(b,c);t2=dis[b]+dis[c]-2*dis[t2];
 96             int t3=LCA(a,c);t3=dis[a]+dis[c]-2*dis[t3];
 97             printf("%lld\n",(t1+t2+t3)/2);
 98         }
 99     }
100     return 0;
101 }
时间: 2024-12-18 13:50:19

[zoj3195]Design the city(LCA)的相关文章

ZOJ3195 Design the city [2017年6月计划 树上问题04]

Design the city Time Limit: 1 Second      Memory Limit: 32768 KB Cerror is the mayor of city HangZhou. As you may know, the traffic system of this city is so terrible, that there are traffic jams everywhere. Now, Cerror finds out that the main reason

ZOJ Design the city LCA转RMQ

Design the city Time Limit: 1 Second      Memory Limit: 32768 KB Cerror is the mayor of city HangZhou. As you may know, the traffic system of this city is so terrible, that there are traffic jams everywhere. Now, Cerror finds out that the main reason

zoj 3195 Design the city lca倍增

题目链接 给一棵树, m个询问, 每个询问给出3个点, 求这三个点之间的最短距离. 其实就是两两之间的最短距离加起来除2. 倍增的lca模板 #include <iostream> #include <vector> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <map> #include <s

ZOJ 3195 Design the city LCA

题目:http://www.icpc.moe/onlinejudge/showProblem.do?problemCode=3195 题意:给定一个树,求三点之间的距离 思路:假定三点为u, v, w,那么(dist[u,v] + dist[v,w] + dist[u,w]) / 2就是答案 总结:wa时不要灰心,也许你离ac不远了 #include<iostream> #include<cstdio> #include<cstring> #include<alg

ZOJ Problem Set - 3195 Design the city 【Tarjan离线LCA】

题目:ZOJ Problem Set - 3195 Design the city 题意:给出一个图,求三点的连起来的距离. 分析:分别求出三点中任意两点的距离 / 2  = ans AC代码: #include <iostream> #include <cstdio> #include <cstring> #include <vector> using namespace std; #define N 50010 #define M 20010 struc

ZOJ 3195 Design the city

倍增法在线LCA..... ZOJ Problem Set - 3195 Design the city Time Limit: 1 Second      Memory Limit: 32768 KB Cerror is the mayor of city HangZhou. As you may know, the traffic system of this city is so terrible, that there are traffic jams everywhere. Now,

ZOJ_3195_Design the city(LCA+tarjan)

Design the city Time Limit: 1000MS   Memory Limit: 32768KB   64bit IO Format: %lld & %llu Submit Status Description Cerror is the mayor of city HangZhou. As you may know, the traffic system of this city is so terrible, that there are traffic jams eve

xtu summer individual 1 C - Design the city

C - Design the city Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%lld & %llu Description Cerror is the mayor of city HangZhou. As you may know, the traffic system of this city is so terrible, that there are traffic jams everywhere.

ZOJ 3195 Design the city(LCA变形)

题意:给定一棵树,求连接三点所需的最短距离. 思路:LCA变形,连接三点的最短距离可以转化为求任意两点距离之和的和再除以二. #include<cstdio> #include<cstring> #include<cmath> #include<cstdlib> #include<iostream> #include<algorithm> #include<vector> #include<map> #incl