zoukankan      html  css  js  c++  java
  • How far away?

    这个题面真的难受,看了好久才看懂。。。

    题目大意:

    给出一个无环图,求图中任意两点的距离(刚开始还以为是最短路。。。)

    好像没有什么思路,爆搜?肯定超时,那可怎么办?

    其实这道题可以用LCA来解决。。。(要不是前一题做的LCA还真想不到。。。)

    首先,我们还是先找根,但是这道题可能不太好找,所以我们就人为的规定输入的x y中x是爸爸,所以找根就找没有出现在y的位置的结点(就是没有爸爸的节点)

    接着我们预处理出每一个节点向上跳2的i次幂到达的位置,以及它到根节点的路径(显然只有一条,题面里给的),还有它的深度。

    接着我们利用倍增法求出两个点的LCA(具体实现看代码)

    答案就是dis[x]+dis[y]-2*dis[LCA(x,y)]  x,y为询问的两个点(想一想正确性,还是比较显然的)

    最后,附上本题代码:

      1 #include<cstdio>
      2 #include<iostream>
      3 #include<cstring>
      4 #define maxn 40000
      5 using namespace std;
      6 
      7 struct EDGE
      8 {
      9     int nxt,to,v;
     10 };
     11 EDGE edge[maxn*2+5];
     12 int T,n,root,cnt,m;
     13 int head[maxn+5],dep[maxn+5],dis[maxn+5];
     14 int f[maxn+5][25];
     15 bool vis[maxn+5];
     16 
     17 void add(int x,int y,int z)
     18 {
     19     edge[++cnt].to=y;
     20     edge[cnt].v=z;
     21     edge[cnt].nxt=head[x];
     22     head[x]=cnt;
     23 }
     24 void pre_fir(int u,int fa)
     25 {
     26     dep[u]=dep[fa]+1;
     27     for(int i=0; i<=22; i++)
     28     {
     29         f[u][i+1]=f[f[u][i]][i];
     30     }
     31     for(int i=head[u]; i; i=edge[i].nxt)
     32     {
     33         if(edge[i].to==fa)
     34         {
     35             continue;
     36         }
     37         dis[edge[i].to]=dis[u]+edge[i].v;
     38         f[edge[i].to][0]=u;
     39         pre_fir(edge[i].to,u);
     40     }
     41 }
     42 int LCA(int x,int y)
     43 {
     44     if(dep[x]<dep[y])
     45     {
     46         swap(x,y);
     47     }
     48     for(int i=22; i>=0; i--)
     49     {
     50         if(dep[f[x][i]]>=dep[y])
     51         {
     52             x=f[x][i];
     53         }
     54         if(x==y)
     55         {
     56             return x;
     57         }
     58     }
     59     for(int i=22; i>=0; i--)
     60     {
     61         if(f[x][i]!=f[y][i])
     62         {
     63             x=f[x][i];
     64             y=f[y][i];
     65         }
     66     }
     67     return f[x][0];
     68 }
     69 int main()
     70 {
     71     scanf("%d",&T);
     72     while(T--)
     73     {
     74         memset(vis,0,sizeof(vis));
     75         memset(edge,0,sizeof(edge));
     76         memset(f,0,sizeof(f));
     77         memset(dep,0,sizeof(dep));
     78         memset(head,0,sizeof(head));
     79         memset(dis,0,sizeof(dis));
     80         cnt=0;
     81         scanf("%d%d",&n,&m);
     82         for(int i=1; i<=n-1; i++)
     83         {
     84             int x,y,z;
     85             scanf("%d%d%d",&x,&y,&z);
     86             vis[y]=1;
     87             add(x,y,z);
     88             add(y,x,z);
     89         }
     90         for(int i=1; i<=n; i++)
     91         {
     92             if(vis[i]==0)
     93             {
     94                 root=i;
     95                 break;
     96             }
     97         }
     98         pre_fir(root,0);
     99         for(int i=1; i<=m; i++)
    100         {
    101             int a,b;
    102             scanf("%d%d",&a,&b);
    103             printf("%d
    ",dis[a]+dis[b]-2*dis[LCA(a,b)]);
    104         }
    105     }
    106     return 0;
    107 }
  • 相关阅读:
    Leetcode 538. Convert BST to Greater Tree
    Leetcode 530. Minimum Absolute Difference in BST
    Leetcode 501. Find Mode in Binary Search Tree
    Leetcode 437. Path Sum III
    Leetcode 404. Sum of Left Leaves
    Leetcode 257. Binary Tree Paths
    Leetcode 235. Lowest Common Ancestor of a Binary Search Tree
    Leetcode 226. Invert Binary Tree
    Leetcode 112. Path Sum
    Leetcode 111. Minimum Depth of Binary Tree
  • 原文地址:https://www.cnblogs.com/yufenglin/p/10575524.html
Copyright © 2011-2022 走看看