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
希望你会好。
↖(^ω^)↗