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 }
  • 相关阅读:
    Java进阶7并发优化4——JDK并发数据结构
    Java 进阶7 并行优化 JDK多任务执行框架技术
    Java进阶7 并发优化2 并行程序设计模式
    Java 进阶7 并发优化 1 并行程序的设计模式
    Java 进阶6 异常处理的陷阱
    Algorithm3: 获得一个int数中二进制位为1 的个数
    Algorithm2: 重复查过半数的元素
    Algorithm1: 全排列
    Java进阶5 面向对象的陷阱
    Java进阶2 数组内存和对象的内存管理知识
  • 原文地址:https://www.cnblogs.com/Yuzao/p/7020239.html
Copyright © 2011-2022 走看看