zoukankan      html  css  js  c++  java
  • 1471. Tree(LCA)

    1471

    先学习了下tarjan算法的LCA 离线算法 它是先知道询问的结点对 在遍历的时候就已经算出来了

    看篇图解 讲的很清楚

     1 #include <iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<stdlib.h>
     6 using namespace std;
     7 #define N 100010
     8 struct node
     9 {
    10     int u,v,w,next;
    11 }ed[N<<2];
    12 int head[N],t,n,q,dis[N];
    13 int vis[N],ans[N],qhead[N<<2];
    14 int father[N],x[N],y[N];
    15 void init()
    16 {
    17     t = 0;
    18     memset(head,-1,sizeof(head));
    19     memset(qhead,-1,sizeof(qhead));
    20 }
    21 void add(int u,int v,int w)
    22 {
    23     ed[t].u = u;
    24     ed[t].v = v;
    25     ed[t].w = w;
    26     ed[t].next = head[u];
    27     head[u] = t++;
    28 }
    29 void add1(int u,int v,int d)
    30 {
    31     ed[t].w = d;
    32     ed[t].u = u;
    33     ed[t].v = v;
    34     ed[t].next = qhead[u];
    35     qhead[u] = t++;
    36 }
    37 int find(int x)
    38 {
    39     if(x!=father[x])
    40     father[x] = find(father[x]);
    41     return father[x];
    42 }
    43 void tarjan(int u)
    44 {
    45     int i;
    46     for(i = qhead[u] ; i!=-1 ; i = ed[i].next)
    47     {
    48         int v = ed[i].v;
    49         if(vis[v])
    50         ans[ed[i].w] = find(v);
    51     }
    52     for(i = head[u] ; i!=-1 ; i = ed[i].next)
    53     {
    54         int v = ed[i].v;
    55         if(!vis[v])
    56         {
    57            vis[v] = 1;
    58            dis[v] = dis[u]+ed[i].w;
    59            tarjan(v);
    60            father[v] = u;
    61         }
    62     }
    63 }
    64 int main()
    65 {
    66     int i,a,b,c;
    67     init();
    68     scanf("%d",&n);
    69     for(i = 0; i < n ; i++)
    70     father[i] = i;
    71     for(i = 1 ; i < n ; i++)
    72     {
    73         scanf("%d%d%d",&a,&b,&c);
    74         add(a,b,c);
    75         add(b,a,c);
    76     }
    77     scanf("%d",&q);
    78     for(i = 1; i <= q ; i++)
    79     {
    80         scanf("%d%d",&x[i],&y[i]);
    81         add1(x[i],y[i],i);
    82         add1(y[i],x[i],i);
    83     }
    84     vis[0] = 1;
    85     tarjan(0);
    86     for(i = 1; i <= q ; i++)
    87     {
    88         printf("%d
    ",dis[x[i]]+dis[y[i]]-2*(dis[ans[i]]));
    89     }
    90     return 0;
    91 }
    View Code
  • 相关阅读:
    http简记
    socket简介
    iOS代理
    ai作图小技能
    按钮切换
    关于ie8背景图片的平铺
    关于文本省略
    关于html table样式
    阿里巴巴iconfont使用方法(超级详细)
    办公电脑安装虚拟机基本就绪
  • 原文地址:https://www.cnblogs.com/shangyu/p/3339437.html
Copyright © 2011-2022 走看看