a 國有 n 座城市,編號從 1 到 n,城市之間有 m 條雙向道路。每一條道路對車輛都有重量限制,簡稱限重。現在有 q 輛貨車在運輸貨物,司機們想知道每輛車在不超過車輛限重的情況下,最多能運多重的貨物。
4 3
1 2 4
2 3 3
3 1 1
31 3
1 4
1 33-13
本題為noip2013提高組day1第三題,首先我們可以看出這是一道求最大生成樹的問題,用kruscal求出,對於我們要找的兩個點,先判斷是否有邊相連,沒有直接輸出-1,然後將選中的邊建成一棵帶權樹,接著我們求lca來求兩點之間的最小載重量,這裡可以去看看lca,我用的是倍增的方法,然後邊求lca邊算兩點到該點的最小值,最後輸出即可。
1uses 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 輛貨車在運輸貨物,司機們想知道每輛車在不超過車輛限重的情況下,最...