1. 程式人生 > >【bzoj3732】Network

【bzoj3732】Network

-- cstring dfs 無向圖 struct cout space efi !=

題目描述

給你N個點的無向圖 (1 <= N <= 15,000),記為:1…N。
圖中有M條邊 (1 <= M <= 30,000) ,第j條邊的長度為: d_j ( 1 < = d_j < = 1,000,000,000).

現在有 K個詢問 (1 < = K < = 20,000)。
每個詢問的格式是:A B,表示詢問從A點走到B點的所有路徑中,最長的邊最小值是多少?


輸入

第一行: N, M, K。
第2..M+1行: 三個正整數:X, Y, and D (1 <= X <=N; 1 <= Y <= N). 表示X與Y之間有一條長度為D的邊。
第M+2..M+K+1行: 每行兩個整數A B,表示詢問從A點走到B點的所有路徑中,最長的邊最小值是多少?


輸出

對每個詢問,輸出最長的邊最小值是多少。


樣例輸入

6 6 8
1 2 5
2 3 4
3 4 3
1 4 8
2 5 7
4 6 2
1 2
1 3
1 4
2 3
2 4
5 1
6 2
6 1


樣例輸出

5
5
5
4
4
7
4
5



題解

kruskal重構樹。在kruskal的時候,如果兩個點不在一個集合裏,那麽新建一個結點作為他們祖先的父親,並將這條邊的邊權賦為新建結點的點權。這樣,原問題就變為在這棵kruskal重構樹上求x,y兩點lca的點權。

// kruskal重構樹 
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include
<cstring> #include<iostream> #include<algorithm> using namespace std; #define ll long long const int maxn=200000+50; int n,m,k,aa,bb,fat[maxn],cnt; int fir[maxn],to[maxn],nex[maxn],ecnt; int son[maxn],dep[maxn],sz[maxn],fa[maxn],top[maxn],val[maxn]; struct node{int x,y,z;}a[maxn]; void
add_edge(int u,int v){ nex[++ecnt]=fir[u];fir[u]=ecnt;to[ecnt]=v; } int cmp(const node &a,const node &b){ return a.z<b.z; } int father(int x){ if(x!=fat[x]) fat[x]=father(fat[x]); return fat[x]; } void dfs1(int x,int f,int deep){ dep[x]=deep; fa[x]=f; sz[x]=1; int maxson=-1; for(int e=fir[x];e;e=nex[e]){ int v=to[e]; if(v==f) continue; dfs1(v,x,deep+1); sz[x]+=sz[v]; if(sz[v]>maxson) maxson=sz[v],son[x]=v; } } void dfs2(int x,int topf){ top[x]=topf; if(!son[x]) return ; dfs2(son[x],topf); for(int e=fir[x];e;e=nex[e]){ int v=to[e]; if(v==fa[x]||v==son[x]) continue; dfs2(v,v); } } template<typename T>void read(T& aa){ char cc; ll ff;aa=0;cc=getchar();ff=1; while((cc<0||cc>9)&&cc!=-) cc=getchar(); if(cc==-) ff=-1,cc=getchar(); while(cc>=0&&cc<=9) aa=aa*10+cc-0,cc=getchar(); aa*=ff; } void kruskal(){ sort(a+1,a+1+m,cmp); for(int i=1;i<=m;i++){ if(father(a[i].x)!=father(a[i].y)){ int fa=father(a[i].x),fb=father(a[i].y); val[++cnt]=a[i].z; fat[cnt]=fat[fa]=fat[fb]=cnt; add_edge(fa,cnt); add_edge(cnt,fa); add_edge(fb,cnt); add_edge(cnt,fb); } } } int lca(int x,int y){ int f1=top[x],f2=top[y]; while(f1!=f2){ if(dep[f1]<dep[f2]) swap(f1,f2),swap(x,y); x=fa[f1];f1=top[x]; } return dep[x]<dep[y]?x:y; } int main(){ read(n),read(m),read(k);cnt=n; for(int i=1;i<=m;i++) read(a[i].x),read(a[i].y),read(a[i].z); for(int i=1;i<=n;i++) fat[i]=i; kruskal(); dfs1(cnt,0,1);dfs2(cnt,cnt); while(k--){ read(aa),read(bb); cout<<val[lca(aa,bb)]<<endl; } return 0; }

【bzoj3732】Network