【 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\n",lca(x,y)); 104 } 105 return 0; 106 }