您的位置:首页 > 其它

NDK 1408 佳佳的魔法药水(Magic Syrup)

2011-09-09 00:34 218 查看
问题描述:

得到一种药水有两种方法:可以按照魔法书上的指导自己配置,也可以到魔法商店里去买 ——那里对于每种药水都有供应,虽然有可能价格很贵。在魔法书上有很多这样的记载:1 份A药水混合1份B药水就可以得到1份C药水。(至于为什么1+1=1,因为……这是魔法世 界)好了,现在你知道了需要得到某种药水,还知道所有可能涉及到的药水的价格以及魔法 书上所有的配置方法,现在要问的就是:1.最少花多少钱可以配制成功这种珍贵的药水;2. 共有多少种不同的花费最少的方案(两种可行的配置方案如果有任何一个步骤不同则视为不
同的)。假定初始时你手中并没有任何可以用的药水。
数据输入:

第一行有一个整数N,表示一共涉及到的药水总数。药水从0~N-1顺序编号,0号药水就是最 终要配制的药水。
第二行有N个整数,分别表示从0~N-1顺序编号的所有药水在魔法商店的价格(都表示1份的 价格)。
第三行开始,每行有3个整数A、B、C,表示1份A药水混合1份B药水就可以得到1份C药 水。注意,某两种特定的药水搭配如果能配成新药水的话,那么结果是唯一的。也就是说不 会出现某两行的A、B相同但C不同的情况。
输入以一个空行结束。
结果输出:

输出两个用空格隔开的整数,分别表示得到0号药水的最小花费以及花费最少的方案的个 数。
样例:

7
10 5 6 3 2 2 3
1 2 0
4 5 1
3 6 2
10 3
核心思想:

很汗颜,很惊人,竟然是图论还是最短路。Dijkstra,每次更新能配制的且花费最小的

var
d,g:array[0..1010]of longint;
a:array[0..1010,0..1010]of longint;
b:array[0..1010]of boolean;
n:longint;
//==================================================
procedure init;
var
i,j,x,y,z:longint;
begin
readln(n);
fori:=1 to n do read(d[i]);
readln;
while not eof do
begin
readln(x,y,z);
inc(x);inc(y);inc(z);
a[x,y]:=z;a[y,x]:=z;
end;
end;
//=============================================
procedure dijkstra;
var
i,j,p,min:longint;
begin
fillchar(b,sizeof(b),false);
fori:=1 to n do g[i]:=1;
fori:=1 to n do
begin
min:=maxlongint;
for j:=1 to n do
if (not b[j])and(d[j]<min) then
begin
min:=d[j];
p:=j;
end;
ifmin>d[1] then continue;
b[p]:=true;
for j:=1 to n do
if (b[j])and(a[p,j]>0) then{<一个是枚举的最小的,一个是确定的,配出来的将为确定的>}
if d[p]+d[j]<d[a[p,j]] then
begin
d[a[p,j]]:=d[p]+d[j];
g[a[p,j]]:=g[p]*g[j];
end
else
if d[p]+d[j]=d[a[p,j]] then g[a[p,j]]:=g[a[p,j]]+g[p]*g[j];
end;
writeln(d[1],' ',g[1]);
end;
//=============================================
begin
assign(input,'p1408.in');reset(input);
assign(output,'p1408.out');rewrite(output);
init;
dijkstra;
close(output);close(output);
end.
题目来源:NDK 1408
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: