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

Sample Output

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 }  
View Code

 

posted @ 2019-09-12 14:37  zjxxcn  阅读(107)  评论(0编辑  收藏  举报