• POJ 1986 DIstance Query LCA水题


    给出一棵树,对于每一个询问,给出2个节点,输出2个节点的距离。

    输入中有字母,那个是没有用的,不用管。

    思路:

    0.选择编号为1的节点作为树的root

    (注意:有些题的边是单向的,这时候我们要根据节点的入度来确定root,

        双向的话一般可以随意选择一个节点作为root)

    1.dfs1,求出dep和pa[i][0]

    2.初始化数组pa

    3.节点(u,v)的权值为w

     把本来是边的权值w赋给u,v中dep较大的节点,

     cost[i]表示节点i的权值为cost[i]

     先初始化:cost[root]=0

    4.dfs2,求每一个节点到root的距离dis[i]

    5.查询:dis(u,v)=dis[u]+dis[v]-2*dis[lca(u,v)];

      1 #include<cstdio>
      2 #include<cstring>
      3 
      4 using namespace std;
      5 
      6 const int maxn=40000+5;
      7 const int inf=0x3f3f3f3f;
      8 
      9 inline int swap(int &x,int &y)
     10 {
     11     x^=y;
     12     y^=x;
     13     x^=y;
     14 }
     15 
     16 struct Edge
     17 {
     18     int to,next;
     19 };
     20 Edge edge[maxn<<1];
     21 int head[maxn];
     22 int tot=0;
     23 int cost[maxn];
     24 int dis[maxn];
     25 int pa[maxn][17];
     26 int dep[maxn];
     27 int e[maxn][3];
     28 
     29 void init()
     30 {
     31     memset(head,-1,sizeof head);
     32     tot=1;
     33     memset(dep,0,sizeof dep);
     34     memset(pa,-1,sizeof pa);
     35 }
     36 
     37 void addedge(int u,int v)
     38 {
     39     edge[tot].to=v;
     40     edge[tot].next=head[u];
     41     head[u]=tot++;
     42 }
     43 
     44 void dfs1(int u)
     45 {
     46     for(int i=head[u];~i;i=edge[i].next)
     47     {
     48         int v=edge[i].to;
     49         if(!dep[v])
     50         {
     51             dep[v]=dep[u]+1;
     52             pa[v][0]=u;
     53             dfs1(v);
     54         }
     55     }
     56 }
     57 
     58 void init_pa(int n)
     59 {
     60     for(int j=1;(1<<j)<=n;j++)
     61     {
     62         for(int i=1;i<=n;i++)
     63         {
     64             if(pa[i][j-1]!=-1)
     65                 pa[i][j]=pa[pa[i][j-1]][j-1];
     66         }
     67     }
     68 }
     69 
     70 void dfs2(int u,int pre)
     71 {
     72     for(int i=head[u];~i;i=edge[i].next)
     73     {
     74         int v=edge[i].to;
     75         if(v==pre)
     76             continue;
     77         dis[v]=dis[u]+cost[v];
     78         dfs2(v,u);
     79     }
     80 }
     81 
     82 int query(int a,int b,int n)
     83 {
     84     int init_a=a;
     85     int init_b=b;
     86     if(dep[a]<dep[b])
     87         swap(a,b);
     88     int cnt;
     89     for(cnt=0;dep[a]-(1<<cnt)>=0;cnt++)
     90         ;
     91     cnt--;
     92     for(int j=cnt;j>=0;j--)
     93     {
     94         if(dep[a]-(1<<j)>=dep[b])
     95             a=pa[a][j];
     96     }
     97     if(a==b)
     98         return dis[init_a]+dis[init_b]-2*dis[a];
     99     for(int i=cnt;i>=0;i--)
    100     {
    101         if(pa[a][i]!=-1&&pa[a][i]!=pa[b][i])
    102         {
    103             a=pa[a][i];
    104             b=pa[b][i];
    105         }
    106     }
    107     return dis[init_a]+dis[init_b]-2*dis[pa[a][0]];
    108 }
    109 
    110 void solve(int n)
    111 {
    112     dep[1]=1;
    113     dfs1(1);
    114     init_pa(n);
    115     cost[1]=0;
    116     dis[1]=0;
    117     for(int i=1;i<=n;i++)
    118     {
    119         if(dep[e[i][0]]>dep[e[i][1]])
    120             swap(e[i][0],e[i][1]);
    121         cost[e[i][1]]=e[i][2];
    122     }
    123     dfs2(1,-1);
    124 
    125     int m;
    126     scanf("%d",&m);
    127     for(int i=1;i<=m;i++)
    128     {
    129         int u,v;
    130         scanf("%d%d",&u,&v);
    131         printf("%d
    ",query(u,v,n));
    132     }
    133     return ;
    134 }
    135 
    136 int main()
    137 {
    138     int n;
    139     while(~scanf("%d",&n))
    140     {
    141         init();
    142         int m;
    143         scanf("%d",&m);
    144         for(int i=1;i<=m;i++)
    145         {
    146             int u,v,w;
    147             char ch;
    148             scanf("%d %d %d %c",&e[i][0],&e[i][1],&e[i][2],&ch);
    149             addedge(e[i][0],e[i][1]);
    150             addedge(e[i][1],e[i][0]);
    151         }
    152         solve(n);
    153     }
    154     return 0;
    155 }
    View Code
  • 相关阅读:
    Java数组排序和搜索
    JDBC排序数据实例
    JDBC Like子句实例
    JDBC WHERE子句条件实例
    JDBC删除数据实例
    JDBC更新数据实例
    JDBC查询数据实例
    JDBC插入数据实例
    JDBC删除表实例
    JDBC创建表实例
  • 原文地址:https://www.cnblogs.com/-maybe/p/4739571.html
Copyright © 2020-2023  润新知