tyvj P1659 - 中中救援队

P1659 - 中中救援队

From 西部314    Normal (OI) 总时限:10s    内存限制:128MB

背景 Background

中中酷爱滑雪,某日突发奇想,带领所有BDEZ的OIER去Alps滑雪,不幸的是,中中和OIER们遭遇了雪崩,除了中中,所有的OIER们都埋在了雪坑里,此时,中中救援队闪亮登场~!(中中救援队只有中中一个人!Orz!)

描述 Description

雪崩之后,出现了N个雪坑,每个雪坑都有一名OIER深陷其中,只有中中幸免,现在中中找到了M条双向道路,每条道路都会连接两个雪坑,但是,由于中中是路痴(-_-||),所以中中希望去除M条道路中尽可能多的道路,但是还要保证任一雪坑都能到达其他的雪坑,所以要先选择留下N-1条道路,中中可以从任意一个雪坑出发,并且任务完成后要回到出发点(起点的雪坑和终点的雪坑也需要消耗体力),而且中中只记得他选择的道路 中中每到一个雪坑i,都会消耗一定的体力值t[i],即使这个雪坑的OIER已被救出。第j条道路连接x,y两个雪坑,而从x到达y也需要消耗体力值energy 由于时间紧迫,中中请你这名OIER帮助他计算下救出这N名OIER所消耗的最小体力值是多少 ——By 宇溟义诚、five213ddking

输入格式 InputFormat

输入第一行两个整数N和M,表示有N名OIER,M条连接的道路 接下来N行,每行一个整数t[i],表示第i个雪坑需要消耗中中的体力值 然后M行,每行三个整数x,y,energy,表示从x坑滑到y坑需要消耗的体力值为energy

输出格式 OutputFormat

第1行,一个整数,为中中消耗的最小体力值

样例输入 SampleInput [复制数据]

5 7
6
5
13
8
18
4 1 7
5 2 5
1 5 16
2 3 20
3 1 18
4 3 12
2 4 15

样例输出 SampleOutput [复制数据]

154

数据范围和注释 Hint

对于30%的数据 5<=N<=100,N-1<=M<=500 1<=t[i]<=100 x<=N,y<=N,x<>y,1<=energy<=100 对于全部数据 5<=N<=10000,N-1<=M<=100000 1<=t[i]<=1000 x<=N,y<=N,x<>y,1<=energy<=1000 结果保证不超过maxlongint

时间限制 TimeLimitation

各个测试点1s
题解:求最小生成树 两点的边权为两个点+距离*2  因为最小生成树无环 一条边走两次
program tyvj1659; type node=record u,v,w:longint; end; var b,f:array[1..10000] of longint; a:array[1..100000] of node; x,y,ans,min,i,n,k,sum,l:longint; procedure qsort(head,tail:longint); var i,j:longint;x:node; begin i:=head;j:=tail;x:=a[head]; while i<j do begin while (i<j)and(a[j].w>=x.w) do dec(j); a[i]:=a[j]; while (i<j)and(a[i].w<=x.w) do inc(i); a[j]:=a[i]; end; a[i]:=x; if head<i-1 then  qsort(head,i-1); if tail>i+1 then  qsort(i+1,tail); end; function find(x:longint):longint; var k:longint; begin k:=f[x]; while f[k]<>k do k:=f[k]; exit(k); end; procedure union(x,y:longint); var k1,k2:longint; begin k1:=find(x); k2:=find(y); f[k1]:=f[k2]; end; begin readln(n,k);min:=maxlongint; for i:=1 to n do begin readln(b[i]); if b[i]<min then min:=b[i]; end; for i:=1 to k do begin readln(a[i].u,a[i].v,a[i].w); a[i].w:=a[i].w*2+b[a[i].u]+b[a[i].v]; end; sum:=0; qsort(1,k); l:=0; for i:=1 to n do f[i]:=i; while sum<n-1 do begin inc(l); x:=find(a[l].u);y:=find(a[l].v); if x<>y  then begin inc(ans,a[l].w); union(x,y); inc(sum); end; end; writeln(ans+min); end.

posted on 2012-10-25 17:15  馒头~blue  阅读(195)  评论(0)    收藏  举报

导航