貨車運輸(codevs 3287)題解

2021-07-09 09:34:38 字數 4239 閱讀 7629

【問題描述】

a 國有 n 座城市,編號從 1 到 n,城市之間有 m 條雙向道路。每一條道路對車輛都有重量限制,簡稱限重。現在有 q 輛貨車在運輸貨物,司機們想知道每輛車在不超過車輛限重的情況下,最多能運多重的貨物。

4 3 

1 2 4 

2 3 3 

3 1 1 

31 3 

1 4 

1 3 3-1

3 本題為noip2013提高組day1第三題,首先我們可以看出這是一道求最大生成樹的問題,用kruscal求出,對於我們要找的兩個點,先判斷是否有邊相連,沒有直接輸出-1,然後將選中的邊建成一棵帶權樹,接著我們求lca來求兩點之間的最小載重量,這裡可以去看看lca,我用的是倍增的方法,然後邊求lca邊算兩點到該點的最小值,最後輸出即可。

1

uses math; 2

const mi:array[0..14]of longint=(1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384

);

3var

n,m,q,tot,i,j,x,y:longint;

4 a,b,v:array[0..50000]of

longint;

5 fa,h:array[0..10000]of

longint;

6 flag:array[0..10000]of

boolean;

7 first,last,next,w:array[0..100000]of

longint;

8 f,g:array[0..10000,0..14]of

longint; 9

function

gf(x:longint):longint; 10

begin

11if fa[x]=x then

12exit(x);

13 fa[x]:=gf(fa[x]); 14

exit(fa[x]); 15

end; 16

procedure swap(var

x,y:longint); 17

vart:longint; 18

begin

19 t:=x;

20 x:=y;

21 y:=t; 22

end; 23

procedure

sort(l,r: longint); 24

var25

i,j,x,y: longint; 26

begin

27 i:=l;

28 j:=r;

29 x:=v[(l+r) div2];

30repeat

31while v[i]>x do

32inc(i); 33

while x>v[j] do

34dec(j); 35

ifnot(i>j) then

36begin

37swap(a[i],a[j]); 38

swap(b[i],b[j]); 39

swap(v[i],v[j]); 40

inc(i);

41 j:=j-1;

42end;

43until i>j; 44

if lthen

45sort(l,j); 46

if ithen

47sort(i,r); 48

end; 49

procedure

insert(x,y,v:longint); 50

begin

51inc(tot);

52 w[tot]:=v;

53 last[tot]:=y;

54 next[tot]:=first[x];

55 first[x]:=tot; 56

end; 57

procedure

dfs(x,dep:longint); 58

vari:longint; 59

begin

60 flag[x]:=true;

61 h[x]:=dep;

62 i:=first[x]; 63

while i<>0

do64

begin

65if

not flag[last[i]] then

66begin

67 f[last[i],0]:=x;

68 g[last[i],0]:=w[i];

69 dfs(last[i],dep+1);

70end;

71 i:=next[i]; 72

end; 73

end; 74

function

ans(x,y:longint):longint; 75

vark:longint; 76

begin

77 ans:=maxlongint; 78

if h[x]then

79swap(x,y); 80

while h[x]>h[y] do

81begin

82 k:=0;

83while h[x]-h[y]>=mi[k+1] do

84inc(k);

85 ans:=min(ans,g[x,k]);

86 x:=f[x,k]; 87

end; 88

while x<>y do

89begin

90if f[x,0]=f[y,0] then

91begin

92 ans:=min(ans,min(g[x,0],g[y,0

])); 93

break; 94

end;

95 k:=0;

96while (f[x,k+1]<>f[y,k+1])and(h[x]>=mi[k+1]) do

97inc(k);

98 ans:=min(ans,min(g[x,k],g[y,k]));

99 x:=f[x,k];

100 y:=f[y,k];

101end

;102

end;

103begin

104readln(n,m);

105for i:=1

to m do

106readln(a[i],b[i],v[i]);

107 sort(1

,m);

108for i:=1

to n do

109 fa[i]:=i;

110for i:=1

to m do

111if gf(a[i])<>gf(b[i]) then

112begin

113 fa[fa[a[i]]]:=fa[b[i]];

114insert(a[i],b[i],v[i]);

115insert(b[i],a[i],v[i]);

116end

;117

for i:=1

to n do

118if

not flag[i] then

119 dfs(1,0

);120 i:=1

;121

while mi[i]do

122begin

123for j:=1

to n do

124if h[j]>=mi[i] then

125begin

126 f[j,i]:=f[f[j,i-1],i-1

];127 g[j,i]:=min(g[j,i-1],g[f[j,i-1],i-1

]);128

end;

129inc(i);

130end

;131

readln(q);

132for i:=1

to q do

133begin

134readln(x,y);

135if gf(x)=gf(y) then

136writeln(ans(x,y))

137else

138 writeln(-1

);139

end;

140end.

codevs 3287 貨車運輸

codevs 3287 貨車運輸 題目描述 description a 國有 n 座城市,編號從 1 到 n,城市之間有 m 條雙向道路。每一條道路對車輛都有重量限制,簡稱限重。現在有 q 輛貨車在運輸貨物,司機們想知道每輛車在不超過車輛限重的情況下,最多能運多重的貨物。輸入描述 input des...

codevs3287 貨車運輸

題目描述 description a 國有 n 座城市,編號從 1 到 n,城市之間有 m 條雙向道路。每一條道路對車輛都有重量限制,簡稱限重。現在有 q 輛貨車在運輸貨物,司機們想知道每輛車在不超過車輛限重的情況下,最多能運多重的貨物。輸入描述 input description 第一行有兩個用乙...

Codevs 3287 貨車運輸

2013年noip全國聯賽提高組 時間限制 1 s 空間限制 128000 kb 題目等級 鑽石 diamond a 國有 n 座城市,編號從 1 到 n,城市之間有 m 條雙向道路。每一條道路對車輛都有重量限制,簡稱限重。現在有 q 輛貨車在運輸貨物,司機們想知道每輛車在不超過車輛限重的情況下,最...