TYVJ P1376 魔域之战
描述
小A成功地在紧要关头逃离了神奇山洞,同时他也感觉自己rp大增。现在他站在了一座阴森森的城堡前,这就是江湖人称“死亡城堡”的魔域。为了rp,小A毅然决然地走了进去……
不愧是死亡城堡,险境丛生,小A又是一个大意的人,XXX他掉进了一个陷阱。
这是一个n*n的矩阵陷阱,矩阵的每一个小格内都有一个魔鬼,并且这些魔鬼属于不同的种类,种类数不超过p(1<=p<=n*n,有可能存在某一种魔鬼不在矩阵中出现)。每一种魔鬼i都有一种战斗力c[i],不同的魔鬼战斗力不同。打魔鬼也不是那么好玩的,需要消耗小A相应数量的战斗力。当小A打败了一个魔鬼后,此种类型的魔鬼就会全部消失,这样小A就可以自由的在这种类型的格子间传送,不会消耗任何的战斗力。每到一个格子,小A可以向紧邻的上下左右四个格子进发去打魔鬼,直到走出矩阵。小A开始郁闷了,他怎样才能从矩阵的第一行出发,顺利的走到矩阵的最后一行呢?所谓的顺利,就是使自己的战斗力大于0。
现在小A求助于聪明的你,希望你能求出小A顺利走出陷阱时剩余的最大战斗力。
输入输出
输入格式
第一行:两个整数n,p;
第2到n+1行是一个n*n的矩阵,矩阵中不同的数字代表不同的格子类型;
第n+2行是p个数,代表p种魔鬼的战斗力;
最后一行:小A的初始战斗力值W。
输出格式
一个整数表示小A顺利走出陷阱时剩余的最大战斗力,如果小A走不出陷阱就输出'Dangerous!';
样例
测试样例1
输入
样例一:
3 3
1 2 1
2 1 2
1 1 1
1 2 5
7
样例二:
3 3
1 2 1
2 1 2
3 3 3
1 2 5
2
输出
样例一:
6
样例二:
Dangerous!
备注
对于30%的数据:1<=n<=50
对于100%的数据:1<=n<=500;w<=maxlongint
分析
因为打败一种魔鬼后,该种魔鬼可以直接到达,所以我们可以在魔鬼种类中连边,只要矩阵中相邻的就连边,然后最后跑最短路即可。
代码如下
program p1376;
type point=^rec;
rec=record
e,v:longint;
s:point;
end;
heaptype=record
dist,doe:longint;
end;
var i,j,n,m,ans:longint;
map:array[1..500,1..500] of longint;
fight:array[1..25002] of longint;
heap:array[1..250002] of heaptype;
ref:array[1..250002] of longint;
visited:array[1..250002] of boolean;
vertex:array[1..250002] of point;
procedure insert(s,e,v:longint);
var p:point;
begin
new(p);
p^.e:=e;
p^.v:=v;
p^.s:=vertex[s];
vertex[s]:=p;
end;
procedure swap(i,j:longint);
var temp:heaptype;
begin
temp:=heap[i];
heap[i]:=heap[j];
heap[j]:=temp;
ref[heap[i].doe]:=i;
ref[heap[j].doe]:=j;
end;
procedure go_up(st,j:longint);
var i:longint;
begin
while (j>>1)>=st do
begin
i:=j>>1;
if heap[i].dist>heap[j].dist
then
begin
swap(i,j);
j:=i;
end
else break;
end;
end;
procedure go_down(i,ed:longint);
var j:longint;
begin
while (i<<1)<=ed do
begin
j:=i<<1;
if (j<ed) and (heap[j].dist>heap[j+1].dist) then inc(j);
if heap[i].dist>heap[j].dist
then
begin
swap(i,j);
i:=j;
end
else break;
end;
end;
procedure dijkstra;
var i,total:longint;
p:point;
begin
total:=m+2;
for i:=1 to m+2 do
begin
heap[i].doe:=i;
heap[i].dist:=maxlongint;
ref[i]:=i;
end;
heap[1].dist:=0;
while (total>0) and (not visited[m+2]) and (heap[1].dist<>maxlongint) do
begin
p:=vertex[heap[1].doe];
while p<>nil do
begin
if heap[ref[p^.e]].dist>heap[1].dist+p^.v
then
begin
heap[ref[p^.e]].dist:=heap[1].dist+p^.v;
go_up(1,ref[p^.e]);
end;
p:=p^.s;
end;
visited[heap[1].doe]:=true;
swap(1,total);
dec(total);
go_down(1,total);
end;
end;
begin
readln(n,m);
for i:=1 to n do
for j:=1 to n do
begin
read(map[i,j]);
map[i,j]:=map[i,j]+1;
end;
for i:=1 to m do
begin
read(fight[i+1]);
visited[i]:=false;
end;
visited[m+1]:=false;
visited[m+2]:=false;
for i:=1 to n do
for j:=1 to n do
begin
if (i>1)
then
begin
insert(map[i-1,j],map[i,j],fight[map[i-1,j]]);
insert(map[i,j],map[i-1,j],fight[map[i,j]]);
end;
if (j>1)
then
begin
insert(map[i,j-1],map[i,j],fight[map[i,j-1]]);
insert(map[i,j],map[i,j-1],fight[map[i,j]]);
end;
if (i=1)
then
begin
insert(1,map[i,j],0);
end;
if (i=n)
then
begin
insert(map[i,j],m+2,fight[map[i,j]]);
end;
end;
dijkstra;
readln(ans);
ans:=ans-heap[ref[m+2]].dist;
if ans<0 then write('Dangerous!')
else write(ans);
end.
评测结果
#0: Accepted (0ms, 6248KiB)
#1: Accepted (0ms, 6284KiB)
#2: Accepted (0ms, 6396KiB)
#3: Accepted (0ms, 6860KiB)
#4: Accepted (31ms, 8796KiB)
#5: Accepted (46ms, 11936KiB)
#6: Accepted (78ms, 14900KiB)
#7: Accepted (46ms, 16400KiB)
#8: Accepted (140ms, 22044KiB)
#9: Accepted (124ms, 22040KiB)