zoukankan      html  css  js  c++  java
  • 【 lca倍增模板】

    题目描述

    对于 n(<100000)个点 n-1 条掉权值的边,有 m 个询问,每条询问求两个结点之间的路径上边权的最小值

    输入

    第一行 n,表示结点个数,接下来 n-1 行,每行 a b w 表示 a 与 b 之间有一条权值为 w的双向边
    第 n+1 行:m 表示询问的个数,接下来 m 行,每行一个询问 a 和 b

    输出

    对于每个询问,输出两个结点的路径上边权的最小值

    样例输入

    10 1 4 11161 3 8 7244 5 9 635 1 10 23999 10 6 23998 7 5 16083 4 3 7145 1 7 20425 3 2 25701 14 1 5 9 3 3 1 7 5 9 1 5 1 1 7 3 1 1 8 1 3 7 6 5 7 7 1 1 7

    样例输出

    16083 635 7145 16083 635 16083 20425 7145 7145 7145 20425 16083 20425 20425
     
    题解:
    发个模版,坑爹数据,dfs栈溢出,于是改成bfs
      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 #include<cmath>
      6 using namespace std;
      7 const int N=100005,INF=1999999999;
      8 int head[N],num=1;
      9 struct Lin
     10 {
     11     int next,to,dis;
     12 }a[N<<1];
     13 void init(int x,int y,int z)
     14 {
     15     a[++num].next=head[x];
     16     a[num].to=y;
     17     a[num].dis=z;
     18     head[x]=num;
     19 }
     20 int gi(){
     21     int str=0,f=1;char ch=getchar();
     22     while(ch>'9' || ch<'0'){if(ch=='-')f=-1;ch=getchar();}
     23     while(ch>='0' && ch<='9')str=str*10+ch-'0',ch=getchar();
     24     return str*f;
     25 }
     26 int n,fa[N][21],dis[N][21],dep[N],q[N];
     27 void bfs()
     28 {
     29     dep[1]=1;
     30     int t=0,sum=1,x,u;
     31     q[1]=1;
     32     while(t!=sum)
     33     {
     34         x=q[++t];
     35         for(int i=head[x];i;i=a[i].next)
     36         {
     37             u=a[i].to;
     38             if(dep[u])continue;
     39             q[++sum]=u;dep[u]=dep[x]+1;
     40             dis[u][0]=a[i].dis;fa[u][0]=x;
     41         }
     42     }
     43 }
     44 int maxdep;
     45 void prework()
     46 {
     47     for(int j=1;j<=maxdep;j++)
     48         for(int i=1;i<=n;i++)
     49             fa[i][j]=fa[fa[i][j-1]][j-1];
     50     for(int j=1;j<=maxdep;j++)
     51         for(int i=1;i<=n;i++)
     52             dis[i][j]=min(dis[i][j-1],dis[fa[i][j-1]][j-1]);
     53 }
     54 void Clear()
     55 {
     56     for(int j=0;j<=maxdep;j++)
     57         for(int i=1;i<=n;i++)dis[i][j]=INF;
     58 }
     59 int lca(int x,int y)
     60 {
     61     if(dep[x]<dep[y])swap(x,y);
     62     int deep=dep[x]-dep[y];
     63     int ans=INF;
     64     for(int i=maxdep;i>=0;i--)
     65     {
     66         if(deep&(1<<i))
     67         {
     68             if(dis[x][i]<ans)ans=dis[x][i];
     69             x=fa[x][i];
     70         }
     71     }
     72     if(x==y)return ans;
     73     for(int i=maxdep;i>=0;i--)
     74     {
     75         if(fa[x][i]!=fa[y][i])
     76         {
     77             if(dis[x][i]<ans)ans=dis[x][i];
     78             if(dis[y][i]<ans)ans=dis[y][i];
     79             x=fa[x][i];y=fa[y][i];
     80         }
     81     }
     82     return min(ans,min(dis[x][0],dis[y][0]));
     83 }
     84 int main()
     85 {
     86     n=gi();
     87     maxdep=log(n)/log(2)+1;
     88     int x,y,z;
     89     Clear();
     90     int ca;
     91     for(int i=1;i<n;i++)
     92     {
     93         x=gi();y=gi();z=gi();
     94         init(x,y,z);init(y,x,z);
     95     }
     96     bfs();
     97     prework();
     98     int m=gi();
     99     while(m--)
    100     {
    101         x=gi();y=gi();
    102         ca=lca(x,y);
    103         printf("%d
    ",lca(x,y));
    104     }
    105     return 0;
    106 }
  • 相关阅读:
    WPF之感触
    C# WinForm 给DataTable中指定位置添加列
    MyEclipse 8.6 download 官方下载地址
    将博客搬至CSDN
    Building Microservices with Spring Cloud
    Building Microservices with Spring Cloud
    Building Microservices with Spring Cloud
    Building Microservices with Spring Cloud
    Building Microservices with Spring Cloud
    Building Microservices with Spring Cloud
  • 原文地址:https://www.cnblogs.com/Yuzao/p/7020239.html
Copyright © 2011-2022 走看看