# [Noi2005]聪聪和可可

[Noi2005]聪聪和可可

Time Limit:10000MS  Memory Limit:65536K
Total Submit:21 Accepted:14

Description

Input

Output

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```

Hint

【样例说明1】

Source

NOI 2005

f[i][j] =

1.i == j ， 0；

2.path[i][j] == j || path[path[i][j]][j] == j ， 1；

3.如果聪聪不能在一次选择中吃到可可，那么她吃到可可的期望就与可可所做的选择有关了

f[i][j] = (f[path[path[i][j]]][j](可可还停留在在j位置) + ∑(f[path[path[i][j]][j]][v])(v表示与j相邻的点) ) / (deg[j] + 1) + 1;(每个选择的概率1 / (deg[j] + 1))

```#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <string.h>
#include <string>
#include <queue>

using namespace std;

const int MAXN = 1000 + 10;
const double eps = 1e-8;
const int inf = 1000000000;
double f[MAXN][MAXN];
int path[MAXN][MAXN];
int deg[MAXN];
int dis[MAXN];
bool vis[MAXN];
int n, m, st, en;

struct Node
{
int v, next;
}edge[MAXN * MAXN];

{
edge[e].v = v;
}

void init()
{
e = 0;
memset(path, -1, sizeof(path));
memset(deg, 0, sizeof(deg));
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
f[i][j] = 0.0;
}
}
}

double dfs(int x, int y)
{
if (x == y) return 0.0;
if (path[x][y] == y || path[path[x][y]][y] == y) return 1.0;
if (!(fabs(f[x][y]) < eps))
{
return f[x][y];
}

double sum = dfs(path[path[x][y]][y], y);
for (int i = head[y]; i != -1; i = edge[i].next)
{
sum += dfs(path[path[x][y]][y], edge[i].v);
}

return f[x][y] = sum / (deg[y] + 1.0) + 1.0;
}

queue <int> q;
void spfa(int u)
{
memset(vis, false, sizeof(vis));
for (int i = 1; i <= n; i++)
{
dis[i] = inf;
}

dis[u] = 0;
vis[u] = true;
q.push(u);

while (!q.empty())
{
int cur = q.front();
q.pop();
vis[cur] = false;

for (int i = head[cur]; i != -1; i = edge[i].next)
{
int v = edge[i].v;
if (!vis[v] && dis[v] > dis[cur] + 1)
{
dis[v] = dis[cur] + 1;
path[v][u] = cur;
q.push(v);
vis[v] = true;
}
else if (dis[v] == dis[cur] + 1)
{
if (cur < path[v][u]) path[v][u] = cur;
}
}
}
}

void input()
{
int u, v;

while (scanf("%d %d", &n, &m) != EOF)
{
scanf("%d %d", &st, &en);
init();

for (int i = 0; i < m; i++)
{
scanf("%d %d", &u, &v);
deg[u]++, deg[v]++;
}

for (int i = 1; i <= n; i++) spfa(i);

printf("%.3lf\n", dfs(st, en));
}
}

int main()
{
input();
return 0;
}
```

http://acmpj.zstu.edu.cn/JudgeOnline/showproblem?problem_id=3926 题目链接

[Noi2005]聪聪和可可,布布扣,bubuko.com

[Noi2005]聪聪和可可

(0)
(0)