由题意知,最后要保留的边肯定都要被走过

来回一条边所花费的时间=2*边长+安慰边两端的牛所要花的时间和

总时间就等于所保留边来回的时间和+根节点时间;

不难想到做一下最小生成树即可

贪心可知,根一定选在需要安慰时间最小的那个点

 1 type node=record
 2        x,y,len:longint;
 3      end;
 4 var a:array[0..100010] of node;
 5     fa,w:array[0..10010] of longint;
 6     n,m,ans,i,j,k1,k2:longint;
 7 
 8 function getf(x:longint):longint;
 9   begin
10     if x<>fa[x] then fa[x]:=getf(fa[x]);
11     exit(fa[x]);
12   end;
13 
14 procedure swap(var a,b:node);
15   var c:node;
16   begin
17     c:=a;
18     a:=b;
19     b:=c;
20   end;
21 
22 procedure sort(l,r:longint);
23   var i,j,p,q: longint;
24   begin
25     i:=l;
26     j:=r;
27     p:=a[(l+r) shr 1].len;
28     repeat
29       while (a[i].len<p) do inc(i);
30       while (p<a[j].len) do dec(j);
31       if not(i>j) then
32       begin
33         swap(a[i],a[j]);
34         inc(i);
35         j:=j-1;
36       end;
37     until i>j;
38     if l<j then sort(l,j);
39     if i<r then sort(i,r);
40   end;
41 
42 begin
43   readln(n,m);
44   ans:=2147483647;
45   for i:=1 to n do
46   begin
47     readln(w[i]);
48     if w[i]<ans then ans:=w[i];
49     fa[i]:=i;
50   end;
51   for i:=1 to m do
52   begin
53     readln(a[i].x,a[i].y,a[i].len);
54     a[i].len:=a[i].len*2+w[a[i].x]+w[a[i].y];
55   end;
56   sort(1,m);
57   i:=0;
58   j:=0;
59   while i<n-1 do
60   begin
61     inc(j);
62     k1:=getf(a[j].x);
63     k2:=getf(a[j].y);
64     if k1<>k2 then
65     begin
66       inc(i);
67       fa[k1]:=k2;
68       ans:=ans+a[j].len;
69     end;
70   end;
71   writeln(ans);
72 end.
View Code

 

posted on 2014-08-12 17:54  acphile  阅读(108)  评论(0编辑  收藏  举报