Description
A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路。每一条道路对车辆都有重量限制,简称限重。现在有 q 辆货车在运输货物,司机们想知道每辆车在不超过车辆限重的情况下,最多能运多重的货物。
Input
第一行有两个用一个空格隔开的整数 n,m,表示 A 国有 n 座城市和 m 条道路。
接下来 m 行每行 3 个整数 x、y、z,每两个整数之间用一个空格隔开,表示从 x 号城市到 y 号城市有一条限重为 z 的道路。注意:x 不等于 y,两座城市之间可能有多条道路。
接下来一行有一个整数 q,表示有 q 辆货车需要运货。
接下来 q 行,每行两个整数 x、y,之间用一个空格隔开,表示一辆货车需要从 x 城市运输货物到 y 城市,注意:x 不等于 y。
接下来 m 行每行 3 个整数 x、y、z,每两个整数之间用一个空格隔开,表示从 x 号城市到 y 号城市有一条限重为 z 的道路。注意:x 不等于 y,两座城市之间可能有多条道路。
接下来一行有一个整数 q,表示有 q 辆货车需要运货。
接下来 q 行,每行两个整数 x、y,之间用一个空格隔开,表示一辆货车需要从 x 城市运输货物到 y 城市,注意:x 不等于 y。
Output
输出共有 q 行,每行一个整数,表示对于每一辆货车,它的最大载重是多少。如果货车不能到达目的地,输出-1。
Sample Input
4 3
1 2 4
2 3 3
3 1 1
3
1 3
1 4
1 3
Sample Output
3
-1
3
Data Constraint
对于 30%的数据,0 < n < 1,000,0 < m < 10,000,0 < q < 1,000;
对于 60%的数据,0 < n < 1,000,0 < m < 50,000,0 < q < 1,000;
对于 100%的数据,0 < n < 10,000,0 < m < 50,000,0 < q < 30,000,0 ≤ z ≤ 100,000。
对于 60%的数据,0 < n < 1,000,0 < m < 50,000,0 < q < 1,000;
对于 100%的数据,0 < n < 10,000,0 < m < 50,000,0 < q < 30,000,0 ≤ z ≤ 100,000。
做法:最大生成树+RMQ+LCA
1 #include <cstdio> 2 #include <iostream> 3 #include <cstring> 4 #include <string> 5 #include <algorithm> 6 #define N 50007 7 using namespace std; 8 int n,m,Q,ans; 9 int ls[N],tot,f[N],dep[N]; 10 int fa[N/4][22],dis[N/4][22]; 11 struct edge{ 12 int to,next; 13 int w; 14 }e[N]; 15 struct arr{ 16 int x,y; 17 int w; 18 }a[N]; 19 20 int Cmp(arr a,arr b){ 21 return a.w>b.w; 22 } 23 24 void Init(){ 25 scanf("%d%d",&n,&m); 26 for (int i=1;i<=m;i++) 27 scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].w); 28 sort(a+1,a+m+1,Cmp); 29 } 30 31 int Find(int x){ 32 if (f[x]==x) return x; 33 return f[x]=Find(f[x]); 34 } 35 36 void Add(int x,int y,int z){ 37 e[++tot].to=y; 38 e[tot].next=ls[x]; 39 e[tot].w=z; 40 ls[x]=tot; 41 } 42 43 void Mst(){ 44 memset(dis,0x7f7f7f7f,sizeof(dis)); 45 for (int i=1;i<=n;i++) f[i]=i; 46 for (int i=1;i<=m;i++){ 47 int u=a[i].x,v=a[i].y; 48 int q=Find(u), p=Find(v); 49 if (q!=p){ 50 Add(u,v,a[i].w); 51 Add(v,u,a[i].w); 52 f[q]=p; 53 } 54 } 55 } 56 57 void Dfs(int x,int pre){ 58 fa[x][0]=pre; 59 dep[x]=dep[pre]+1; 60 for (int i=ls[x];i;i=e[i].next){ 61 int v=e[i].to; 62 if (v==pre) continue; 63 dis[v][0]=e[i].w; 64 Dfs(v,x); 65 } 66 } 67 68 void Lca(int x,int y){ 69 if (dep[x]<dep[y]) swap(x,y); 70 for (int i=20;i>=0;i--) 71 if (dep[fa[x][i]]>=dep[y]){ 72 ans=min(ans,dis[x][i]); 73 x=fa[x][i]; 74 } 75 if (x==y) return; 76 for (int i=20;i>=0;i--) 77 if (fa[x][i]!=fa[y][i]){ 78 ans=min(ans,min(dis[x][i],dis[y][i])); 79 x=fa[x][i],y=fa[y][i]; 80 } 81 ans=min(ans,min(dis[x][0],dis[y][0])); 82 } 83 84 void Work(){ 85 scanf("%d",&Q); 86 while (Q--){ 87 int x,y; 88 scanf("%d%d",&x,&y); 89 if (Find(x)!=Find(y)){ 90 printf("-1 "); 91 continue; 92 } 93 else{ 94 ans=0x7f7f7f7f; 95 Lca(x,y); 96 printf("%d ",ans); 97 } 98 } 99 } 100 101 int main(){ 102 Init(); 103 Mst(); 104 Dfs(1,0); 105 for (int j=1;j<=20;j++) 106 for (int i=1;i<=n;i++){ 107 fa[i][j]=fa[fa[i][j-1]][j-1]; 108 dis[i][j]=min(dis[i][j-1],dis[fa[i][j-1]][j-1]); 109 } 110 111 Work(); 112 }