BZOJ 1415: [Noi2005]聪聪和可可
2015-12-09 20:24
225 查看
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1415
题意:
有一个无向图,有N个景点1-N,有E条路。
可可在景点M处,之后每个时间单位,可可会选择去相邻的景点中的一个或停留在原景点不动。去这些地方的概率是相等的。
聪聪开始在景点C,聪聪会选择一个更靠近可可的景点,如果这样的景点有多个,则会选择一个标号最小的景点。
如果走完第一步以后仍然没吃到可可,她还可以在本段时间内再向可可走近一步。
在每个时间单位,聪聪先走,可可后走,若某时刻处于同一景点,则可可被吃到了。
求平均情况下,聪聪几步可以吃掉可可。
思路:
预处理出P[i][j]表示聪聪在i点可可在j点,聪聪下一步要到达的点。
dp[i][j]表示聪聪在i点可可在j点,聪聪抓住可可的平均步数。
dp[0][0] = 0,如果P[P[i][j]][j] = j 或 P[i][j] = j,那么dp[i][j] = 1。
除这两种情况,聪聪下一步的位置是P[P[i][j]][j],可可下一步是w[j][k]。概率为1/(j的度数+1)
那么可以得到递推式dp[i][j]=(segma(dp[p[p[i][j]][j][w[j][k]])+dp[p[p[i][j]][j]][j])/(t[i]+1) + 1
题意:
有一个无向图,有N个景点1-N,有E条路。
可可在景点M处,之后每个时间单位,可可会选择去相邻的景点中的一个或停留在原景点不动。去这些地方的概率是相等的。
聪聪开始在景点C,聪聪会选择一个更靠近可可的景点,如果这样的景点有多个,则会选择一个标号最小的景点。
如果走完第一步以后仍然没吃到可可,她还可以在本段时间内再向可可走近一步。
在每个时间单位,聪聪先走,可可后走,若某时刻处于同一景点,则可可被吃到了。
求平均情况下,聪聪几步可以吃掉可可。
思路:
预处理出P[i][j]表示聪聪在i点可可在j点,聪聪下一步要到达的点。
dp[i][j]表示聪聪在i点可可在j点,聪聪抓住可可的平均步数。
dp[0][0] = 0,如果P[P[i][j]][j] = j 或 P[i][j] = j,那么dp[i][j] = 1。
除这两种情况,聪聪下一步的位置是P[P[i][j]][j],可可下一步是w[j][k]。概率为1/(j的度数+1)
那么可以得到递推式dp[i][j]=(segma(dp[p[p[i][j]][j][w[j][k]])+dp[p[p[i][j]][j]][j])/(t[i]+1) + 1
/* * Problem: * Created Time: 2015/12/9 15:55:15 * File Name: test.cpp */ //#include <bits/stdc++.h> #include <iostream> #include <cstring> #include <cstdio> #include <string> #include <queue> #include <vector> using namespace std; int N, E, C, M; #define maxn 1010 vector <int> mp[maxn]; int p[maxn][maxn]; double dp[maxn][maxn]; int dist[maxn]; int t[maxn]; int min(int a, int b) { return a<b?a:b; } void bfs(int s) { queue <int> q; q.push(s); int vis[maxn]; memset(vis, 0, sizeof(vis)); memset(dist, -1, sizeof(dist)); dist[s] = 0; vis[s] = 1; while(!q.empty()) { int u = q.front(); q.pop(); for(int i = 0; i < mp[u].size(); i++) { if(dist[mp[u][i]] == -1) { dist[mp[u][i]] = dist[u]+1; p[mp[u][i]][s] = u; q.push(mp[u][i]); } else if(dist[mp[u][i]] == dist[u]+1) p[mp[u][i]][s] = min(p[mp[u][i]][s], u); } } } double dfs(int from, int to) { if(dp[from][to] != -1) return dp[from][to]; if(from == to) return dp[from][to] = 0; if(p[from][to] == to || p[p[from][to]][to] == to) return dp[from][to] = 1.0; double sum = dfs(p[p[from][to]][to], to); //留在原地 for(int i = 0; i < mp[to].size(); i++) { sum += dfs(p[p[from][to]][to], mp[to][i]); } sum /= (t[to]+1.0); sum += 1; return dp[from][to] = sum; } int main() { // freopen("in.txt", "r", stdin); while(~scanf("%d%d", &N, &E)) { scanf("%d%d", &C, &M); for(int i = 1; i <= N; i++) mp[i].clear(); memset(t, 0, sizeof(t)); for(int i = 1; i <= E; i++) { int a, b; scanf("%d%d", &a, &b); t[a]++; t[b]++; mp[a].push_back(b); mp[b].push_back(a); } memset(p, -1, sizeof(p)); for(int i = 1; i <= N; i++) bfs(i); for(int i = 1; i <= N; i++) { for(int j = 1; j <= N; j++) dp[i][j] = -1; } double ans = dfs(C, M); printf("%.3lf\n", ans); } return 0; }
相关文章推荐
- c++
- linux下history(历史)命令用法详解
- Android Java(2015-6-18 15:28、2016-1-30 21:18)
- leetcode -- Reorder List -- 重点,很适合作为面试题
- Scala IED For Eclipse
- SIFT特征检测
- redhat linux 设置yum
- 深入分析JavaWeb Item11 -- session会话管理
- lightoj1301Monitoring Processes
- Xcode7 —https适配问题
- php源码分析之php_info输出中css样式是怎么来的
- Tomcat 开启 SSL
- Leetcode题解(八)
- 网页设计大赛总结
- C语言词法及语法定义-Lex,Yacc
- c++11多线程入门实例
- 解决wordpress发表文章,照片不能居中的问题
- UIImageView的图片居中问题
- 其实今天没有欲望..-MySQLi
- 关于面向对象“封装”的理解