Codevs P3287 货车运输

6 篇文章 0 订阅
3 篇文章 0 订阅

Codevs P3287 货车运输


题目描述 Description

A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路。每一条道路对车辆都有重量限制,简称限重。现在有 q 辆货车在运输货物,司机们想知道每辆车在不超过车辆限重的情况下,最多能运多重的货物。


输入输出 Input&Output


输入描述 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


样例输入 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。


分析

因为要求最大运输量,显然是在最大路径上的最小边权,也就是最大生成树上的路径,由此建树lca即可。

代码如下

program p3287;
type point=^rec;
     rec=record
      e,v:longint;
      s:point;
     end;
     rec2=record
      s,e,v:longint;
     end;
var n,m,x,y,z,i,j,sum,q,s,e,minn:longint;
    g,father:array[0..10000,0..20] of longint;
    map:array[1..1000] of rec2;
    vertex:array[0..10000] of point;
    visited:array[0..10000] of boolean;
    depth:array[0..10000] of longint;
function min(a,b:longint):longint;
begin
 if a<b then exit(a);
 exit(b);
end;

procedure qsort(i,j:longint);
var l,r,mid:longint;
    temp:rec2;
begin
 l:=i;
 r:=j;
 mid:=map[(l+r)>>1].v;
 while l<=r do
  begin
   while map[l].v>mid do inc(l);
   while map[r].v<mid do dec(r);
   if l<=r then
    begin
     temp:=map[l];
     map[l]:=map[r];
     map[r]:=temp;
     inc(l);
     dec(r);
    end;
  end;
 if i<r then qsort(i,r);
 if l<j then qsort(l,j);
end;

procedure insert(s,e,v:longint);
var p:point;
begin
 new(p);
 p^.e:=e;
 p^.v:=v; 
 p^.s:=vertex[s];
 vertex[s]:=p;
end;

function find(x:longint):longint;
begin
 if father[x,0]=x then exit(x);
 father[x,0]:=find(father[x,0]);
 exit(father[x,0]);
end;

procedure union(s,e,i:longint);
begin
 father[find(father[e,0]),0]:=find(father[s,0]);
 insert(e,s,map[i].v);
 insert(s,e,map[i].v);
end;

procedure kruscal;
var i:longint;
begin
 for i:=0 to n do father[i,0]:=i;
 for i:=1 to n+m do
  begin
   if find(map[i].s)<>find(map[i].e)
    then
     begin
      union(map[i].s,map[i].e,i);
     end;
  end;
end;

procedure dfs(head,step:longint);
var p:point;
begin
 visited[head]:=true;
 p:=vertex[head];
 while p<>nil do
  begin
   if not visited[p^.e]
    then
     begin
      father[p^.e,0]:=head;
      depth[p^.e]:=step;
      g[p^.e,0]:=p^.v;
      dfs(p^.e,step+1);
     end;
   p:=p^.s;
  end;
end;

function lca(s,e:longint):longint;
var j:longint;
begin
 if depth[s]<depth[e]
  then
   begin
    j:=s;
    s:=e;
    e:=j;
   end;
 while depth[s]>depth[e] do
  begin
   for j:=20 downto 0 do
    begin
     if depth[father[s,j]]>=depth[e]
      then
       begin
        minn:=min(g[s,j],minn);
        s:=father[s,j];
       end;
    end;
  end;
 if s=e then exit(s);
 for j:=20 downto 0 do
  begin
   if father[s,j]<>father[e,j]
    then
     begin
      minn:=min(minn,g[s,j]);
      minn:=min(minn,g[e,j]);
      s:=father[s,j];
      e:=father[e,j];
     end;
  end;
 minn:=min(min(minn,g[s,0]),g[e,0]);
 exit(father[s,0]);
end;

begin
 readln(n,m);
 for i:=1 to m do
  begin
   readln(x,y,z);
   map[i].s:=x;
   map[i].e:=y;
   map[i].v:=z;
  end;
 for i:=1 to n do
  begin
   map[i+m].s:=0;
   map[i+m].e:=i;
   map[i+m].v:=-1;
  end;
 qsort(1,n+m);
 kruscal;
 dfs(0,1);
 depth[0]:=0;
 father[0,0]:=0;
 for j:=1 to 20 do
  for i:=0 to n do
   begin
    father[i,j]:=father[father[i,j-1],j-1];
    g[i,j]:=min(g[i,j-1],g[father[i,j-1],j-1]);
   end;
 readln(q);
 for i:=1 to q do
  begin
   readln(s,e);
   minn:=maxlongint;
   if lca(s,e)=0
    then writeln(-1)
    else writeln(minn);
  end;
end.

评测结果

运行结果
测试点#truck1.in 结果:AC 内存使用量: 256kB 时间使用量: 0ms
测试点#truck10.in 结果:AC 内存使用量: 1004kB 时间使用量: 27ms
测试点#truck11.in 结果:AC 内存使用量: 1004kB 时间使用量: 30ms
测试点#truck12.in 结果:AC 内存使用量: 1004kB 时间使用量: 28ms
测试点#truck13.in 结果:AC 内存使用量: 3312kB 时间使用量: 66ms
测试点#truck14.in 结果:AC 内存使用量: 2928kB 时间使用量: 64ms
测试点#truck15.in 结果:AC 内存使用量: 3180kB 时间使用量: 60ms
测试点#truck16.in 结果:AC 内存使用量: 3184kB 时间使用量: 61ms
测试点#truck17.in 结果:AC 内存使用量: 3440kB 时间使用量: 63ms
测试点#truck18.in 结果:AC 内存使用量: 2924kB 时间使用量: 61ms
测试点#truck19.in 结果:AC 内存使用量: 2800kB 时间使用量: 58ms
测试点#truck2.in 结果:AC 内存使用量: 256kB 时间使用量: 0ms
测试点#truck20.in 结果:AC 内存使用量: 2928kB 时间使用量: 60ms
测试点#truck3.in 结果:AC 内存使用量: 492kB 时间使用量: 4ms
测试点#truck4.in 结果:AC 内存使用量: 492kB 时间使用量: 5ms
测试点#truck5.in 结果:AC 内存使用量: 496kB 时间使用量: 8ms
测试点#truck6.in 结果:AC 内存使用量: 496kB 时间使用量: 4ms
测试点#truck7.in 结果:AC 内存使用量: 1008kB 时间使用量: 32ms
测试点#truck8.in 结果:AC 内存使用量: 1008kB 时间使用量: 28ms
测试点#truck9.in 结果:AC 内存使用量: 1008kB 时间使用量: 28ms

NOIP。。。一等。。。自己好差。。。要死了。。。

如果能够重来多好,如果我只会让你烦躁,讨厌,那我该怎么做?。。。

TOO naive

希望你会好。

↖(^ω^)↗

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值