• 货车运输


    题目描述 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.
  • 相关阅读:
    Win7 华硕电脑自带摄像头无法打开 方法思路介绍
    P3520 [POI2011]SMI-Garbage
    二分图的最大匹配(模板)
    #数列分块入门 2
    数列分块入门#1
    线段树(标记下传乘法和加法)
    最小费用最大流
    最大流算法(模板)
    编译器出现/mingw32/bin/ld.exe:Permission denied 错误
    1298 圆与三角形
  • 原文地址:https://www.cnblogs.com/zjhl2/p/3930154.html
Copyright © 2020-2023  润新知