bzoj3732: Network
最小生成树的性质 任意两点间最大边最小
不会写倍增系列= =
1 #include<bits/stdc++.h> 2 #define rep(i,l,r) for(int i=l;i<=r;++i) 3 using namespace std; 4 const int N=102333; 5 int tot,dep[N],sz[N],f[N],fa[N][25],s[N][25],x,y,a,b,c,n,m,K,now,mn,top[N],son[N],head[N],cnt; 6 struct Edge{ 7 int to,next,w; 8 }e[N]; 9 struct zs{ 10 int a,b,c; 11 }e1[N]; 12 int find(int x){ 13 return f[x]==x?x:f[x]=find(f[x]); 14 } 15 bool cmp(zs a,zs b){ 16 return a.c<b.c; 17 } 18 inline void ins(int u,int v,int w){ 19 e[++tot].to=v; e[tot].next=head[u]; head[u]=tot; e[tot].w=w; 20 } 21 inline void dfs1(int x,int pre) { 22 dep[x]=dep[pre]+1; 23 for(int k=head[x];k;k=e[k].next) { 24 if(e[k].to==pre) continue; 25 fa[e[k].to][0]=x; 26 s[e[k].to][0]=e[k].w; 27 dfs1(e[k].to,x); 28 } 29 } 30 inline int work(int x,int y){ 31 int mx=0; 32 if(dep[x]<dep[y]) swap(x,y); 33 for(int j=20;j>=0;--j) 34 if(fa[x][j]&&dep[fa[x][j]]>=dep[y]) mx=max(mx,s[x][j]),x=fa[x][j]; 35 if(x==y)return mx; 36 for(int j=20;j>=0;--j) if(fa[x][j]&&fa[y][j]&&fa[x][j]!=fa[y][j]){ 37 mx=max(mx,s[x][j]); mx=max(mx,s[y][j]); 38 x=fa[x][j]; y=fa[y][j]; 39 } 40 mx=max(mx,max(s[x][0],s[y][0])); 41 return mx; 42 } 43 int main(){ 44 scanf("%d%d%d",&n,&m,&K); 45 rep(i,1,m)scanf("%d%d%d",&e1[i].a,&e1[i].b,&e1[i].c); 46 sort(e1+1,e1+1+m,cmp); 47 rep(i,1,n)f[i]=i; 48 rep(i,1,m){ 49 x=find(e1[i].a); y=find(e1[i].b); c=e1[i].c; 50 if(x!=y){ 51 f[x]=y; 52 ins(e1[i].a,e1[i].b,c); 53 ins(e1[i].b,e1[i].a,c); 54 } 55 } 56 dfs1(1,0); 57 rep(j,1,20) rep(x,1,n)fa[x][j]=fa[fa[x][j-1]][j-1],s[x][j]=max(s[x][j-1],s[fa[x][j-1]][j-1]); 58 while(K--){ 59 scanf("%d%d",&a,&b); 60 printf("%d\n",work(a,b)); 61 } 62 }