其他分享
首页 > 其他分享> > Distance Queries

Distance Queries

作者:互联网

题目链接:http://poj.org/problem?id=1986

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 const int maxn=40010;
 6 int n, m, k; 
 7 struct edge{
 8     int to, next, weight;
 9 }e[maxn<<1];
10 int head[maxn], tot;
11 void add(int u, int v, int w){
12     e[++tot].to=v;
13     e[tot].weight=w;
14     e[tot].next=head[u];
15     head[u]=tot;
16 }
17 int lg[maxn+10];
18 void lg2(){
19     lg[0]=-1;
20     for(int i=1; i<=maxn; i++)lg[i]=lg[i/2]+1;
21 }
22 int dep[maxn], f[maxn][30], dis[maxn];//通过dfs计算节点深度、与根节点距离以及初始化f[i][0] 
23 void dfs(int u){
24     for(int i=head[u]; i; i=e[i].next)    {
25         int v=e[i].to;
26         if(f[u][0] == v)//避免来回访问 
27             continue;
28         dep[v]=dep[u]+1;
29         dis[v]=dis[u]+e[i].weight;
30         f[v][0]=u;
31         dfs(v);
32     }
33 }
34 void st_create(){
35     for(int j=1; j<=lg[maxn]; j++)
36         for(int i=1; i<=n; i++)
37             f[i][j]=f[f[i][j-1]][j-1];
38 }
39 int lca(int x, int y){
40     if(dep[x] < dep[y])swap(x, y);//假定x深度大于y深度 
41     while(dep[x]>dep[y])//x节点找祖先到和y节点的深度相同 
42         x=f[x][lg[dep[x]-dep[y]]];
43     if(x==y)
44         return x;//y是x的祖先 
45     for(int i=lg[maxn]; i>=0; i--)//同时找祖先,直到祖先不同 
46         if(f[x][i] != f[y][i])
47             x=f[x][i], y=f[y][i];
48     return f[x][0];//返回祖先 
49 }
50 int main()
51 {
52     scanf("%d%d",&n, &m);
53     while(m--){
54         int a, b,c;
55         scanf("%d%d%d", &a, &b, &c);
56         getchar();getchar();
57         add(a, b, c); add(b, a, c);
58     }
59     lg2();//功能等同于log2()函数 
60     dfs(1);//从1开始访问节点 
61     st_create();
62     scanf("%d",&k);
63     while(k--){
64         int a, b;
65         scanf("%d%d",&a,&b);
66         int ab=lca(a, b);
67         printf("%d\n",dis[a]+dis[b]-2*dis[ab]);
68     }
69     return 0;
70 }

 

标签:Distance,return,int,scanf,d%,祖先,Queries,include
来源: https://www.cnblogs.com/tflsnoi/p/16171144.html