Input
数据的第1行为两个整数N和E,以空格分隔,分别表示森林中的景点数和连接相邻景点的路的条数。 第2行包含两个整数C和M,以空格分隔,分别表示初始时聪聪和可可所在的景点的编号。 接下来E行,每行两个整数,第i+2行的两个整数Ai和Bi表示景点Ai和景点Bi之间有一条路。 所有的路都是无向的,即:如果能从A走到B,就可以从B走到A。 输入保证任何两个景点之间不会有多于一条路直接相连,且聪聪和可可之间必有路直接或间接的相连。
Output
输出1个实数,四舍五入保留三位小数,表示平均多少个时间单位后聪聪会把可可吃掉。
Sample Input
【输入样例1】
4 3
1 4
1 2
2 3
3 4
【输入样例2】
9 9
9 3
1 2
2 3
3 4
4 5
3 6
4 6
4 7
7 8
8 9
Sample Output
【输出样例1】
1.500
【输出样例2】
2.167
PoPo大爷写了非常详解的题解,http://blog.csdn.net/PoPoQQQ/article/details/40896403 对蒟蒻来说这个题的信
息量还是很大的,但实际上又很水,这就是信息学的魅力吧。
首先我们知道,由于聪聪走两步而可可走一步,所以聪聪一定能在有限的时刻追上可可,而且两人的距离随着时间进行
单调递减
于是我们记忆化搜索
首先用预处理出一个数组p[i][j],表示当聪聪在点i,可可在点j时聪聪下一步走哪个点 这个从每个点出发跑一遍SPFA就
可以处理出来
然后就可以记忆化搜索了 令f[i][j]为当聪聪在点i,可可在点j时的期望相遇时
若i==j 则f[i][j]=0
若p[i][j]==j||p[p[i][j]][j]==j则f[i][j]=1
否则令temp=p[p[i][j]][j],则有
我为了不统计度数,直接加了一条自己到自己的边,然后直接BFS,懒得spfa了。
//BZOJ 1415
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1010;
const int inf=0x3f3f3f3f;
struct edge{
int v, nxt;
edge(){}
edge(int v,int nxt):v(v), nxt(nxt){}
}E[maxn*5];
int head[maxn], edgecnt;
void init(){
edgecnt = 0;
memset(head, -1, sizeof(head));
}
void add(int u, int v){
E[edgecnt].v=v,E[edgecnt].nxt=head[u],head[u]=edgecnt++;
}
int dist[maxn][maxn], p[maxn][maxn];
///p[i][j]聪聪在i点可可在j点,聪聪下一步走哪个点
int n, m, s, t;
double f[maxn][maxn];
bool vis[maxn][maxn];
double dfs(int x, int y)
{
if(vis[x][y]) return f[x][y];
vis[x][y]=1;
if(dist[x][y]==0) return f[x][y]=0.0;
if(dist[x][y]<=2) return f[x][y]=1.0;
double val = 0;
int cnt=0;
for(int i=head[y];~i;i=E[i].nxt){
cnt++;
val+=dfs(p[p[x][y]][y],E[i].v);
}
return f[x][y]=val/cnt+1.0;
}
queue <int> que;
void bfs(int s)
{
que.push(s);
dist[s][s]=0;
while(!que.empty()){
int u=que.front(); que.pop();
for(int i=head[u];~i;i=E[i].nxt){
int v=E[i].v;
if(dist[s][v]==-1){
dist[s][v]=dist[s][u]+1;
que.push(v);
}
}
}
}
int main(){
scanf("%d%d%d%d", &n,&m,&s,&t);
init();
while(m--){
int a,b;
scanf("%d%d", &a, &b);
add(a, b);
add(b, a);
}
memset(dist, -1, sizeof(dist));
for(int k=1; k<=n; k++){
bfs(k);
for(int j=1; j<=n; j++){
if(j!=k){
int mx = inf;
for(int i=head[j];~i;i=E[i].nxt){
if(mx>dist[k][E[i].v]){
mx = dist[k][E[i].v];
p[j][k]=E[i].v;
}
else if(mx==dist[k][E[i].v]){
p[j][k]=min(p[j][k],E[i].v);
}
}
}
}
}
for(int i=1; i<=n; i++) add(i,i);
printf("%.3lf\n", dfs(s, t));
return 0;
}