吐槽鬼体面。。到底问的是什么。。。其实问的不是时间,是步数的期望。
首先预处理一个dis数组,dis[x][y]表示从x到y的最短路步数因为边权为1,可以bfs,当然我写的spfa(我懒)。
从题目我们可以发现,zhx是一定会 被 吃了的,毕竟机器人走两步zhx走一步,所以只需考虑他们不断逼近的情况。
设f[x][y] 表示这一秒开始时,机器人在x,zhx在y时,机器人吃到zhx的期望天数,当x=y时, f[x][y]=0。
当dis[x][y]≤2时,f[x][y]=1,设w为x能到达的最接近y的点,设du[y] 为y能到达的点的个数,
设p为走一步或不走的概率,则p=1/(du[y]+1),设y下一个可能到 达的点为v,f[x][y] = (f[w][y]+Σf[w][v])*p+1。这一步可以递归求解。
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
using namespace std;
struct node
{
int to;
int nxt;
}edge[2005];
int head[1005];
int cnt = 1;
void init()
{
memset(head,-1,sizeof(head));
}
void add(int from,int to)
{
edge[cnt].to = to;
edge[cnt].nxt = head[from];
head[from] = cnt++;
}
int dis[1005][1005];
int used[1005][1005];
int choose[1005][1005];
double f[1005][1005];
int du[1005];
void spfa(int rt)
{
dis[rt][rt] = 0;
used[rt][rt] = 1;
queue<int>M;
M.push(rt);
while(!M.empty())
{
int u = M.front();
M.pop();
for(int i = head[u];i != -1;i = edge[i].nxt)
{
int to = edge[i].to;
if(dis[rt][to]>dis[rt][u]+1)
{
dis[rt][to] = dis[rt][u]+1;
if(!used[rt][to])
{
used[rt][to] = 1;
M.push(to);
}
}
}
used[rt][u] = 0;
}
}
double gett(int x,int y)
{
if(f[x][y] != -1.0)return f[x][y];
if(x == y)return f[x][y] = 0.0;
if(dis[x][y] <= 2)return f[x][y] = 1.0;
f[x][y] = 0;
double p = 1.0/(du[y]+1);
int w = choose[choose[x][y]][y];
for(int i = head[y];i != -1;i = edge[i].nxt)
{
int to = edge[i].to;
f[x][y] += gett(w,to);
}
f[x][y] += gett(w,y);
f[x][y] *= p;
f[x][y]++;
return f[x][y];
}
int main()
{
init();
int n,e;
scanf("%d%d",&n, &e);
int c,m;
scanf("%d%d", &c, &m);
for(int i = 1;i <= e;i++)
{
int a,b;
scanf("%d%d", &a, &b);
add(a,b);
add(b,a);
du[a]++,du[b]++;
}
for(int i = 1;i <= n;i++)
{
for(int j = 1;j <= n;j++)
{
f[i][j] = -1.0;
}
}
memset(dis,0x3f,sizeof(dis));
for(int i = 1;i <= n;i++)
{
spfa(i);
}
memset(choose,0x3f,sizeof(choose));
for(int i = 1;i <= n;i++)
{
for(int j = 1;j <= n;j++)
{
if(dis[i][j] == 0x3f3f3f3f)continue;
for(int k = head[i];k != -1;k = edge[k].nxt)
{
int to = edge[k].to;
if(dis[i][j] == dis[to][j]+1 && choose[i][j] > to)
{
choose[i][j] = to;
}
}
}
}
printf("%.3lf",gett(c,m));
return 0;
}