2435: [Noi2011]道路修建
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2188 Solved: 639
[ Submit][ Status]
Description
在 W 星球上有 n 個國家。為了各自國家的經濟發展,他們決定在各個國家
之間建設雙向道路使得國家之間連通。但是每個國家的國王都很吝嗇,他們只願
意修建恰好 n – 1條雙向道路。 每條道路的修建都要付出一定的費用, 這個費用等於道路長度乘以道路兩端的國家個數之差的絕對值。例如,在下圖中,虛線所示道路兩端分別有 2 個、4個國家,如果該道路長度為 1,則費用為1×|2 – 4|=2。圖中圓圈里的數字表示國家的編號。
由於國家的數量十分龐大,道路的建造方案有很多種,同時每種方案的修建
費用難以用人工計算,國王們決定找人設計一個軟件,對於給定的建造方案,計
算出所需要的費用。請你幫助國王們設計一個這樣的軟件。
Input
輸入的第一行包含一個整數n,表示 W 星球上的國家的數量,國家從 1到n
編號。接下來 n – 1行描述道路建設情況,其中第 i 行包含三個整數ai、bi和ci,表
示第i 條雙向道路修建在 ai與bi兩個國家之間,長度為ci。
Output
輸出一個整數,表示修建所有道路所需要的總費用。
Sample Input
6
1 2 1
1 3 1
1 4 2
6 3 1
5 2 1
Sample Output
20
HINT
n = 1,000,000 1≤ai, bi≤n
0 ≤ci≤ 10^6
Source
題解:其實就是個搜索,由於題目中給了一棵樹,所以直接建樹,然后求出每個點有多少子孫(算自己)。。。本身應該不難的,但是對於P黨問題來了——BFS嘛,搞死了還是超時(坑爹的int64運算簡直慢到哭);DFS呵呵直接爆棧不解釋(對於C++黨的linux下系統棧無限表示嚴重鄙視!!TT傳送門 ),於是我還是壯烈的TLE了,求神犇幫助(不過程序算法應該沒有問題,就是int64害得......)
BFS:
2 point=^node;
3 node= record
4 g,w:longint;
5 next:point;
6 end;
7
8 var
9 i,j,k,l,m,n:longint;ll:int64;
10 a: array[ 0.. 1000000] of point;
11 c,b,d,e: array[ 0.. 1000500] of longint;
12 p:point;
13 procedure add(x,y,z:longint);inline;
14 var
15 p:point;
16 begin
17 new(p);
18 p^.g:=y;
19 p^.w:=z;
20 p^.next:=a[x];
21 a[x]:=p;
22 end;
23 procedure bfs1;inline;
24 var
25 p:point;f,r:longint;
26 begin
27 b[ 1]:= 1;d[ 1]:= 1;
28 f:= 1;r:= 2;
29 while f<r do
30 begin
31 p:=a[d[f]];
32 while p<> nil do
33 begin
34 if b[p^.g]= 0 then
35 begin
36 b[d[f]]:= 2;
37 b[p^.g]:= 1;
38 c[p^.g]:=d[f];
39 d[r]:=p^.g;
40 inc(r);
41 end;
42 p:=p^.next;
43 end;
44 inc(f);
45 end;
46 end;
47 begin
48 readln(n);
49 for i:= 1 to n do a[i]:= nil;
50 for i:= 1 to n- 1 do
51 begin
52 readln(j,k,l);
53 add(j,k,l);
54 add(k,j,l);
55 end;
56 fillchar(b,sizeof(b), 0);ll:= 0;
57 fillchar(c,sizeof(c), 0);fillchar(d,sizeof(d), 0);
58 bfs1;ll:= 0;
59 for i:=n downto 1 do
60 begin
61 e[d[i]]:= 1;
62 p:=a[d[i]];
63 while p<> nil do
64 begin
65 if p^.g<>c[d[i]] then
66 begin
67 ll:=ll+int64(abs(e[p^.g]-(n-e[p^.g])))*int64(p^.w);
68 e[d[i]]:=e[d[i]]+e[p^.g];
69 end;
70 p:=p^.next;
71 end;
72 end;
73 writeln(ll);
74 readln; end .
DFS:
1 type 2 point=^node; 3 node=record 4 g,w:longint; 5 next:point; 6 end; 7 8 var 9 i,j,k,l,m,n:longint;ll:int64; 10 a:array[0..1000000] of point; 11 c,b:array[0..1000000] of longint; 12 procedure add(x,y,z:longint);inline; 13 var 14 p:point; 15 begin 16 new(p); 17 p^.g:=y; 18 p^.w:=z; 19 p^.next:=a[x]; 20 a[x]:=p; 21 end; 22 procedure dfs(x:longint);inline; 23 var 24 p:point; 25 begin 26 if b[x]=1 then exit; 27 p:=a[x];b[x]:=1; 28 while p<>nil do 29 begin 30 if b[p^.g]=0 then 31 begin 32 dfs(p^.g); 33 ll:=ll+int64(int64(abs(int64(c[p^.g])-int64(int64(n)-int64(c[p^.g]))))*int64(p^.w)); 34 c[x]:=c[x]+c[p^.g]; 35 end; 36 p:=p^.next; 37 end; 38 end; 39 begin 40 readln(n); 41 for i:=1 to n do 42 begin 43 c[i]:=1; 44 a[i]:=nil; 45 end; 46 for i:=1 to n-1 do 47 begin 48 readln(j,k,l); 49 add(j,k,l); 50 add(k,j,l); 51 end; 52 fillchar(b,sizeof(b),0);ll:=0; 53 dfs(1); 54 writeln(ll); 55 end.