Sweet Butter
香甜的黄油
译 by kd
农夫John发现做出全威斯康辛州最甜的黄油的方法: 糖。把糖放在一片牧场上,他知道N(1<=N<=500)只奶牛会过来舔它,这样就能做出能卖好价钱的超甜黄油。当然,他将付出额外的费用在 奶牛上。
农夫John很狡猾。像以前的Pavlov,他知道他可以训练这些奶牛,让它们在听到铃声时去一个特定的牧场。他打算将糖放在那里然后下午发出铃声,以至他可以在晚上挤奶。
农夫John知道每只奶牛都在各自喜欢的牧场(一个牧场不一定只有一头牛)。给出各头牛在的牧场和牧场间的路线,找出使所有牛到达的路程和最短的牧场(他 将把糖放在那)
PROGRAM NAME: butter
INPUT FORMAT
第一行: 三个数:奶牛数N,牧场数(2<=P<=800),牧场间道路数C(1<=C<=1450)
第二行到第N+1行: 1到N头奶牛所在的牧场号
第N+2行到第N+C+1行: 每行有三个数:相连的牧场A、B,两牧场间距离D(1<=D<=255),当然,连接是双向的
SAMPLE INPUT (file butter.in)
3 4 5
2
3
4
1 2 1
1 3 5
2 3 7
2 4 3
3 4 5
{样例图形
P2 P1 @--1--@ C1 \ |\ \ | \ 5 7 3 \ | \ \| \ C3 C2 @--5--@ P3 P4 }
OUTPUT FORMAT
一行 输出奶牛必须行走的最小的距离和SAMPLE OUTPUT (file butter.out)
8
{说明:
放在4号牧场最优
}
枚举每个牧场k,求出其余所有牧场到此牧场的最短路径。
每次可以得到一个值tot,为各个牧场的奶牛数*该牧场到s最短路径。
取所有tot 最小的即可。
求最短路径用spfa+链式前向星
var i,n,p,c,dd,d1,d2,d3,ans:longint;
num,d:array[1..800]of longint;
h:array[1..20000]of longint;
v:array[1..800]of boolean;
w,next,e,head:array[1..3000]of longint;
procedure insert(a,b,s,i:longint);
begin
next[i]:=head[a];
e[i]:=b;
w[i]:=s;
head[a]:=i;
end;
procedure spfa(k:longint);
var i,hea,tail,s,tot,kk:longint;
begin
fillchar(h,sizeof(h),0);
fillchar(v,sizeof(v),false);
for i:=1 to p do d[i]:=maxlongint;
d[k]:=0;hea:=1;tail:=1;h[1]:=k;v[k]:=true;
while hea<=tail do
begin
s:=h[hea];
kk:=head[s];
while kk<>0 do
begin
if (w[kk]+d[s]<d[e[kk]]) then
begin
d[e[kk]]:=w[kk]+d[s];
if (v[e[kk]]<>true) then
begin
inc(tail);
h[tail]:=e[kk];
v[e[kk]]:=true;
end;
end;
kk:=next[kk];
end;
v[s]:=false;
inc(hea);
end;
tot:=0;
for i:=1 to p do if num[i]<>0 then tot:=tot+num[i]*d[i];
if ans>tot then ans:=tot;
end;
begin
fillchar(head,sizeof(head),0);
fillchar(next,sizeof(next),0);
readln(n,p,c);ans:=maxlongint;
for i:=1 to n do begin read(dd); inc(num[dd]); end;
for i:=1 to c do
begin
readln(d1,d2,d3);
insert(d1,d2,d3,i*2);
insert(d2,d1,d3,i*2+1);
end;
for i:=1 to p do
spfa(i);
writeln(ans);
end.