【 lca倍增模板】
2017-06-15 21:41
176 查看
题目描述
对于 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
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using namespace std; const int N=100005,INF=1999999999; int head ,num=1; struct Lin { int next,to,dis; }a[N<<1]; void init(int x,int y,int z) { a[++num].next=head[x]; a[num].to=y; a[num].dis=z; head[x]=num; } int gi(){ int str=0,f=1;char ch=getchar(); while(ch>'9' || ch<'0'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0' && ch<='9')str=str*10+ch-'0',ch=getchar(); return str*f; } int n,fa [21],dis [21],dep ,q ; void bfs() { dep[1]=1; int t=0,sum=1,x,u; q[1]=1; while(t!=sum) { x=q[++t]; for(int i=head[x];i;i=a[i].next) { u=a[i].to; if(dep[u])continue; q[++sum]=u;dep[u]=dep[x]+1; dis[u][0]=a[i].dis;fa[u][0]=x; } } } int maxdep; void prework() { for(int j=1;j<=maxdep;j++) for(int i=1;i<=n;i++) fa[i][j]=fa[fa[i][j-1]][j-1]; for(int j=1;j<=maxdep;j++) for(int i=1;i<=n;i++) dis[i][j]=min(dis[i][j-1],dis[fa[i][j-1]][j-1]); } void Clear() { for(int j=0;j<=maxdep;j++) for(int i=1;i<=n;i++)dis[i][j]=INF; } int lca(int x,int y) { if(dep[x]<dep[y])swap(x,y); int deep=dep[x]-dep[y]; int ans=INF; for(int i=maxdep;i>=0;i--) { if(deep&(1<<i)) { if(dis[x][i]<ans)ans=dis[x][i]; x=fa[x][i]; } } if(x==y)return ans; for(int i=maxdep;i>=0;i--) { if(fa[x][i]!=fa[y][i]) { if(dis[x][i]<ans)ans=dis[x][i]; if(dis[y][i]<ans)ans=dis[y][i]; x=fa[x][i];y=fa[y][i]; } } return min(ans,min(dis[x][0],dis[y][0])); } int main() { n=gi(); maxdep=log(n)/log(2)+1; int x,y,z; Clear(); int ca; for(int i=1;i<n;i++) { x=gi();y=gi();z=gi(); init(x,y,z);init(y,x,z); } bfs(); prework(); int m=gi(); while(m--) { x=gi();y=gi(); ca=lca(x,y); printf("%d\n",lca(x,y)); } return 0; }
相关文章推荐