Description Input 数据的第1行为两个整数N和E,以空格分隔,分别表示森林中的景点数和连接相邻景点的路的条数。
第2行包含两个整数C和M,以空格分隔,分别表示初始时聪聪和可可所在的景点的编号。
接下来E行,每行两个整数,第i+2行的两个整数Ai和Bi表示景点Ai和景点Bi之间有一条路。
所有的路都是无向的,即:如果能从A走到B,就可以从B走到A。
输入保证任何两个景点之间不会有多于一条路直接相连,且聪聪和可可之间必有路直接或间接的相连。 Output
输出1个实数,四舍五入保留三位小数,表示平均多少个时间单位后聪聪会把可可吃掉。
记
dp[i][j]
表示猫在点
i
,老鼠在点
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int oo=0x3f3f3f3f;
int fir[1010],ne[2010],to[2010],f[1010][1010],que[2010],from[2010],dis[2010],
n,m;
double dp[1010][1010];
void add(int num,int u,int v)
{
ne[num]=fir[u];
fir[u]=num;
to[num]=v;
}
double dfs(int u,int v)
{
if (dp[u][v]>=0) return dp[u][v];
if (u==v) return dp[u][v]=0;
if (f[u][v]==v||f[f[u][v]][v]==v) return dp[u][v]=1;
int x=f[f[u][v]][v],cnt=1;
for (int i=fir[v];i;i=ne[i]) cnt++;
dp[u][v]=1+dfs(x,v)/cnt;
for (int i=fir[v];i;i=ne[i]) dp[u][v]+=dfs(x,to[i])/cnt;
return dp[u][v];
}
int main()
{
int hd,tl,u,v,s,t;
scanf("%d%d%d%d",&n,&m,&s,&t);
for (int i=1;i<=m;i++)
{
scanf("%d%d",&u,&v);
add(i<<1,u,v);
add(i<<1|1,v,u);
}
for (int i=1;i<=n;i++)
{
for (int j=1;j<=n;j++) dis[j]=oo;
dis[i]=0;
hd=1,tl=0;
for (int j=fir[i];j;j=ne[j])
{
dis[v=to[j]]=1;
que[++tl]=v;
from[v]=v;
}
while (hd<=tl)
{
u=que[hd++];
f[i][u]=from[u];
for (int j=fir[u];j;j=ne[j])
if (dis[u]+1<dis[v=to[j]]||(dis[u]+1==dis[v]&&from[u]<from[v]))
{
if (dis[v]==oo) que[++tl]=v;
dis[v]=dis[u]+1;
from[v]=from[u];
}
}
}
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
dp[i][j]=-1;
printf("%.3f\n",dfs(s,t));
}