题目描述 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.