因为这几次考试中的倍增孤都挂了,而且发现自己倍增打得比较少,所以用一篇随笔来水再学习。
直接开题:
题意:给定一张图,每条边上有限重,有Q个询问,每个询问求x到y的最大运输重量。
开局思路暴力?一看范围……
算了吧,要是孤还想活着就别这么打……
我们再看一下,也就是说x到y中间有很多道路,我们要求出这些道路最小值的最大值。
不妨先考虑如何保证最大,我们可以从中选出一些边,保证联通的情况下有最小值的最大值
诶,好像就是要构一棵最大生成树,再跑LCA就可以啦(毕竟暴跳就会TLE啊)
上代码:
#include<bits/stdc++.h> using namespace std; inline int read() { int f=1,w=0;char x=0; while(x<'0'||x>'9') {if(x=='-') f=-1; x=getchar();} while(x!=EOF&&x>='0'&&x<='9') {w=(w<<3)+(w<<1)+(x^48);x=getchar();} return w*f; } int n,m,num_edge,fa[200001][21],w[200001][21],q; struct Edge{int u,v,w;} line[200001]; int head[50001],f[200001],vis[200001],dep[200001]; struct Tree{int next,to,dis;} edge[200001]; inline bool cmp(Edge a,Edge b) {return a.w>b.w;} inline int find(int x) {return f[x]==x?x:f[x]=find(f[x]);} inline void add(int from,int to,int dis) { edge[++num_edge].next=head[from]; edge[num_edge].to=to; edge[num_edge].dis=dis; head[from]=num_edge; } void dfs(int pos) { vis[pos]=1; for(int i=head[pos];i;i=edge[i].next) if(!vis[edge[i].to]) { dep[edge[i].to]=dep[pos]+1; fa[edge[i].to][0]=pos; w[edge[i].to][0]=edge[i].dis; dfs(edge[i].to); } } inline int LCA(int x,int y) { if(find(x)!=find(y)) return -1; if(dep[x]>dep[y]) swap(x,y); int ans=999999999; for(int i=20;i>=0;i--) if(dep[fa[y][i]]>=dep[x]) { ans=min(ans,w[y][i]); y=fa[y][i]; } if(x==y) return ans; for(int i=20;i>=0;i--) if(fa[x][i]!=fa[y][i]) { ans=min(ans,min(w[x][i],w[y][i])); y=fa[y][i]; x=fa[x][i]; } ans=min(ans,min(w[x][0],w[y][0])); return ans; } int main(){ n=read(); m=read(); for(int i=1;i<=m;i++) line[i].u=read(),line[i].v=read(),line[i].w=read(); sort(line+1,line+m+1,cmp); for(int i=1;i<=n;i++) f[i]=i; for(int i=1;i<=m;i++) { int u=find(line[i].u); int v=find(line[i].v); if(u!=v) f[u]=v,add(line[i].u,line[i].v,line[i].w),add(line[i].v,line[i].u,line[i].w); } for(int i=1;i<=n;i++) if(!vis[i]) { dep[i]=1; dfs(i); fa[i][0]=i; w[i][0]=999999999; } for(int j=1;j<=20;j++) for(int i=1;i<=n;i++) { fa[i][j]=fa[fa[i][j-1]][j-1]; w[i][j]=min(w[i][j-1],w[fa[i][j-1]][j-1]); } q=read(); for(int i=1;i<=q;i++) { int x=read(),y=read(); printf("%d ",LCA(x,y)); } }