题解:求最大生成树,则边一定在最大生成树上,证明用Kluscal
然后就是倍增
TMD我竟然建树写错了,MDMDMDMDMDMD
为什么一开始没想到QWQ
总结:不要往难处想
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int maxn=30009;int n,m,T;struct Edge{int u,v,d;}edges[maxn];bool cmp(const Edge &rhs1,const Edge &rhs2){return rhs1.d<rhs2.d;}int father[maxn];int Getf(int x){if(father[x]==x)return x;return father[x]=Getf(father[x]);}void Unionn(int x,int y){int fx=Getf(x);int fy=Getf(y);if(fx!=fy)father[fx]=fy;}int cntedge;int head[maxn];int to[maxn<<1],nex[maxn<<1],dist[maxn];void Addedge(int x,int y,int z){nex[++cntedge]=head[x];to[cntedge]=y;dist[cntedge]=z;head[x]=cntedge;}int f[maxn][20],g[maxn][20],dep[maxn];void Dfs(int now,int fa){dep[now]=dep[fa]+1;for(int i=head[now];i;i=nex[i]){if(to[i]==fa)continue;f[to[i]][0]=now;g[to[i]][0]=dist[i];Dfs(to[i],now);}}void LCAinit(){for(int j=1;j<=19;++j){for(int i=1;i<=n;++i){f[i][j]=f[f[i][j-1]][j-1];g[i][j]=max(g[i][j-1],g[f[i][j-1]][j-1]);}}}int GetMaxd(int u,int v){int ret=0;if(dep[u]<dep[v])swap(u,v);for(int j=19;j>=0;--j){if(dep[f[u][j]]>=dep[v]){ret=max(ret,g[u][j]);u=f[u][j];}}if(u==v)return ret;for(int j=19;j>=0;--j){if(f[u][j]!=f[v][j]){ret=max(ret,max(g[u][j],g[v][j]));u=f[u][j];v=f[v][j];}}return max(ret,max(g[u][0],g[v][0]));}int main(){scanf("%d%d%d",&n,&m,&T);for(int i=1;i<=m;++i)scanf("%d%d%d",&edges[i].u,&edges[i].v,&edges[i].d);sort(edges+1,edges+1+m,cmp);for(int i=1;i<=n;++i)father[i]=i;for(int i=1;i<=m;++i){int u=edges[i].u;int v=edges[i].v;int d=edges[i].d;if(Getf(u)==Getf(v))continue;Unionn(u,v);Addedge(u,v,d);Addedge(v,u,d);}Dfs(1,0);LCAinit();////for(int i=1;i<=n;++i){//printf("%d %d\n",f[i][0],g[i][0]);//}while(T--){int x,y;scanf("%d%d",&x,&y);printf("%d\n",GetMaxd(x,y));}return 0;}
BZOJ 3732 Network
原文地址:https://www.cnblogs.com/zzyer/p/8475976.html