bzoj 3732: Network
Description
给你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点的所有路径中,最长的边最小值是多少?
Input
第一行: 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点的所有路径中,最长的边最小值是多少?
Output
对每个询问,输出最长的边最小值是多少。
Sample Input
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
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
Sample Output
5
5
5
4
4
7
4
5
5
5
4
4
7
4
5
HINT
1 <= N <= 15,000
1 <= M <= 30,000
1 <= d_j <= 1,000,000,000
1 <= K <= 15,000
本题可以用最大生成树+lca来做,当然也可以kruskal重构图来做。
1 #include<bits/stdc++.h> 2 using namespace std; 3 int const N=15000+3; 4 struct edge{ 5 int to,nt; 6 }e[N<<1]; 7 struct E{ 8 int x,y,z; 9 bool operator < (const E &rhs) const{ 10 return z<rhs.z; 11 } 12 }a[N<<1]; 13 int f[N<<1],top[N<<1],size[N<<1],son[N<<1],val[N<<1],dep[N<<1]; 14 int n,m,k,cnt,h[N<<1],id; 15 int find(int x){ 16 return x==f[x]? x: f[x]=find(f[x]); 17 } 18 void add(int a,int b){ 19 e[++cnt].to=b; 20 e[cnt].nt=h[a]; 21 h[a]=cnt; 22 } 23 void kruscal(){ 24 sort(a+1,a+m+1); 25 id=n; 26 for(int i=1;i<2*n;i++) f[i]=i; 27 for(int i=1;i<=m;i++){ 28 int fx=find(a[i].x); 29 int fy=find(a[i].y); 30 if(fx!=fy){ 31 id++; 32 val[id]=a[i].z; 33 f[fx]=f[fy]=id; 34 add(id,fx); 35 add(id,fy); 36 } 37 if(id==2*n-1) break; 38 } 39 } 40 void dfs(int x,int fa,int d){ 41 f[x]=fa; dep[x]=d; size[x]=1; 42 for(int i=h[x];i;i=e[i].nt){ 43 int v=e[i].to; 44 dfs(v,x,d+1); 45 size[x]+=size[v]; 46 if(size[son[x]]<size[v]) son[x]=v; 47 } 48 } 49 void dfs2(int x,int tp){ 50 top[x]=tp; 51 if(son[x]) dfs2(son[x],tp); 52 for(int i=h[x];i;i=e[i].nt){ 53 int v=e[i].to; 54 if(v==son[x]) continue; 55 dfs2(v,v); 56 } 57 } 58 int query(int x,int y){ 59 while (top[x]^top[y]){ 60 int fx=top[x]; 61 int fy=top[y]; 62 if(dep[fx]<dep[fy]) 63 swap(x,y),swap(fx,fy); 64 x=f[fx]; 65 } 66 return dep[x]<dep[y]? val[x]:val[y]; 67 } 68 int main(){ 69 scanf("%d%d%d",&n,&m,&k); 70 for(int i=1;i<=m;i++){ 71 scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z); 72 } 73 kruscal(); 74 dfs(id,0,0); 75 dfs2(id,id); 76 while(k--){ 77 int x,y; 78 scanf("%d%d",&x,&y); 79 printf("%d\n",query(x,y)); 80 } 81 return 0; 82 }