题目描述 Description
A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路。每一条道路对车辆都有重量限制,简称限重。现在有 q 辆货车在运输货物,司机们想知道每辆车在不超过车辆限重的情况下,最多能运多重的货物。
输入描述 Input Description
第一行有两个用一个空格隔开的整数 n,m,表示 A 国有 n 座城市和 m 条道路。
接下来 m 行每行 3 个整数 x、y、z,每两个整数之间用一个空格隔开,表示从 x 号城市到 y 号城市有一条限重为 z 的道路。注意:x 不等于 y,两座城市之间可能有多条道路。
接下来一行有一个整数 q,表示有 q 辆货车需要运货。
接下来 q 行,每行两个整数 x、y,之间用一个空格隔开,表示一辆货车需要从 x 城市运输货物到 y 城市,注意:x 不等于 y。
输出描述 Output Description
输出共有 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 Size & Hint
对于 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。
求一下最大生成树,然后保持两点的深度相同找最近公共祖先(我打了一个暴力求最近公共祖先的方法,全过了)
type lu=record x,y,z:longint; end; var a:array[1..50000]of lu; way:array[1..20000]of lu; f,st,en,deep,back,long:array[1..10000]of longint; b:array[1..10000]of boolean; n,m,mm,i,j,f1,f2,q,x1,x2,num,min:longint; procedure qsorta(l,r:longint); var i,j,mid:longint; t:lu; begin i:=l; j:=r; mid:=a[random(j-i)+i].z; repeat while a[i].z>mid do inc(i); while a[j].z<mid do dec(j); if i<=j then begin t:=a[i]; a[i]:=a[j]; a[j]:=t; inc(i); dec(j); end; until i>j; if i<r then qsorta(i,r); if j>l then qsorta(l,j); end; procedure qsortw(l,r:longint); var i,j,mid:longint; t:lu; begin i:=l; j:=r; mid:=way[random(j-i)+i].x; repeat while way[i].x<mid do inc(i); while way[j].x>mid do dec(j); if i<=j then begin t:=way[i]; way[i]:=way[j]; way[j]:=t; inc(i); dec(j); end; until i>j; if i<r then qsortw(i,r); if j>l then qsortw(l,j); end; function find(x:longint):longint; begin if f[x]=x then find:=x else find:=find(f[x]); f[x]:=find; end; procedure dfs(d:longint); var i,v:longint; begin b[d]:=true; if st[d]=0 then exit; for i:=st[d] to en[d] do if not b[way[i].y] then begin v:=way[i].y; deep[v]:=deep[d]+1; back[v]:=d; long[v]:=way[i].z; dfs(v); end; end; begin randomize; read(n,m); for i:=1 to m do read(a[i].x,a[i].y,a[i].z); qsorta(1,m); for i:=1 to n do f[i]:=i; for i:=1 to m do begin f1:=find(a[i].x); f2:=find(a[i].y); if f1<>f2 then begin f[f2]:=f1; inc(num); inc(mm); way[mm].x:=a[i].x; way[mm].y:=a[i].y; way[mm].z:=a[i].z; end; end; for i:=1 to mm do begin way[i+mm].x:=way[i].y; way[i+mm].y:=way[i].x; way[i+mm].z:=way[i].z; end; mm:=mm*2; qsortw(1,mm); st[way[1].x]:=1; en[way[mm].x]:=mm; for i:=1 to mm-1 do if way[i].x<>way[i+1].x then begin en[way[i].x]:=i; st[way[i+1].x]:=i+1; end; for i:=1 to n do begin if not b[i] then begin b[i]:=true; deep[i]:=1; dfs(i); end; end; read(q); for i:=1 to q do begin read(x1,x2); if find(x1)<>find(x2) then begin writeln(-1); continue; end; min:=maxlongint; while deep[x1]>deep[x2] do begin if long[x1]<min then min:=long[x1]; x1:=back[x1]; end; while deep[x2]>deep[x1] do begin if long[x2]<min then min:=long[x2]; x2:=back[x2]; end; while x1<>x2 do begin if long[x1]<min then min:=long[x1]; if long[x2]<min then min:=long[x2]; x1:=back[x1]; x2:=back[x2]; end; writeln(min); end; end.