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