聪聪与可可
在一个魔法森林里,住着一只聪明的小猫聪聪和一只可爱的小老鼠可可。 整个森林可以认为是一个无向图,图中有N个美丽的景点,景点从1至N编号。在景点之间有一些路连接。 可可正在景点M (M ≤ N)处。以后的每个时间单位,可可都会选择去相邻的景点(可能有多个)中的一个或停留在原景点不动。而去这些地方所发生的概率是相等的。 聪聪是很聪明的,所以,当她在景点C时,她会选一个更靠近可可的景点,如果这样的景点有多个,她会选一个标号最小的景点。如果走完第一步以后仍然没吃到可可,她还可以在本段时间内再向可可走近一步。 在每个时间单位,假设聪聪先走,可可后走。在某一时刻,若聪聪和可可位于同一个景点,则可可就被吃掉了。
问平均情况下,聪聪几步就可能吃到可可。
n、e<=1000
noi2005,原题懒得贴了
首先预处理每个点往每个点应当走的下一个点,即为p[i,j]
然后动规
用f[i,j]表示猫在i老鼠在j的平均步数
记忆化搜索一下就好了
program cchkk;
var
tot,n,e,i,j,k,u,v,c,m:longint;
dl,t,root:array [0..1001] of longint;
p,dis:array [0..1001,0..1001] of longint;
f:array [0..1001,0..1001] of double;
yes:array [0..1001,0..1001] of boolean;
point,next:array [0..2001] of longint;
procedure connect (u,v:longint);
begin
inc(tot);
point[tot]:=v;
next[tot]:=root[u];
root[u]:=tot;
inc(t[u]);
end;
procedure spfa (sta:longint);
var
i,j,k:longint;
begin
tot:=1;
dl[1]:=sta;
i:=1;
dis[sta,sta]:=0;
while i<=tot do
begin
k:=root[dl[i]];
while k<>0 do
begin
if dis[sta,point[k]]>dis[sta,dl[i]]+1 then
begin
dis[sta,point[k]]:=dis[sta,dl[i]]+1;
inc(tot);
dl[tot]:=point[k];
end;
if (dis[sta,point[k]]=dis[sta,dl[i]]+1)and
(p[point[k],sta]>dl[i]) then p[point[k],sta]:=dl[i];
k:=next[k];
end;
inc(i);
end;
end;
function search (x,y:longint):double;
var
i,k:longint;
ans:double;
begin
if yes[x,y] then exit(f[x,y]);
if p[x,y]=y then
begin
yes[x,y]:=true;
f[x,y]:=1;
exit(1);
end;
ans:=0;
if p[p[x,y],y]=y then
ans:=ans+t[y]/(t[y]+1)
else
begin
k:=root[y];
while k<>0 do
begin
ans:=ans+(search(p[p[x,y],y],point[k])+1)/(t[y]+1);
k:=next[k];
end;
end;
ans:=ans+(search(p[p[x,y],y],y)+1)/(t[y]+1);
f[x,y]:=ans;
yes[x,y]:=true;
exit(ans);
end;
begin
assign(input,'cchkk.in');
reset(input);
assign(output,'cchkk.out');
rewrite(output);
read(n,e);
read(c,m);
for i:=1 to e do
begin
read(u,v);
connect(u,v);
connect(v,u);
end;
fillchar(dis,sizeof(dis),63);
fillchar(p,sizeof(p),63);
for i:=1 to n do
spfa(i);
fillchar(yes,sizeof(yes),false);
for i:=1 to n do
begin
f[i,i]:=0;
yes[i,i]:=true;
end;
writeln(search(c,m):0:3);
close(input);
close(output);
end.