HDU-5001 Walk (概率DP)
2015-09-11 13:45
330 查看
[align=left]Problem Description[/align]
I used to think I could be anything, but now I know that I couldn't do anything. So I started traveling.
The
nation looks like a connected bidirectional graph, and I am randomly
walking on it. It means when I am at node i, I will travel to an
adjacent node with the same probability in the next step. I will pick up
the start node randomly (each node in the graph has the same
probability.), and travel for d steps, noting that I may go through some
nodes multiple times.
If I miss some sights at a node, it will
make me unhappy. So I wonder for each node, what is the probability that
my path doesn't contain it.
[align=left]Input[/align]
The first line contains an integer T, denoting the number of the test cases.
For
each test case, the first line contains 3 integers n, m and d, denoting
the number of vertices, the number of edges and the number of steps
respectively. Then m lines follows, each containing two integers a and
b, denoting there is an edge between node a and node b.
T<=20,
n<=50, n-1<=m<=n*(n-1)/2, 1<=d<=10000. There is no
self-loops or multiple edges in the graph, and the graph is connected.
The nodes are indexed from 1.
[align=left]Output[/align]
For each test cases, output n lines, the i-th line containing the desired probability for the i-th node.
Your answer will be accepted if its absolute error doesn't exceed 1e-5.
[align=left]Sample Input[/align]
2
5 10 100
1 2
2 3
3 4
4 5
1 5
2 4
3 5
2 5
1 4
1 3
10 10 10
1 2
2 3
3 4
4 5
5 6
6 7
7 8
8 9
9 10
4 9
[align=left]Sample Output[/align]
0.0000000000
0.0000000000
0.0000000000
0.0000000000
0.0000000000
0.6993317967
0.5864284952
0.4440860821
0.2275896991
0.4294074591
0.4851048742
0.4896018842
0.4525044250
0.3406567483
0.6421630037
题目大意:给一张无根无向图(n个节点,m条边),每一步走哪一个儿子节点的概率相同(以哪个点为起点的概率也相同)。对于每个点,找出走完d步后走不到该点的概率。
题目分析:定义dp(s,u)表示不经过节点i(1<=i<=n)走了s步时,到达u点的概率。则根据加法原理,dp(s,son)=sum(dp(s-1,u)*f),其中 f 是u走到其儿子son的概率,f=1.0/(u的儿子个数)。题目要求分别输出不经过节点 i (1<=i<=n) 的答案,则DP n次即可。对于每次DP,根据加法原理,答案为ans=sum(dp(d,j)),其中,j不等于i。
注意:第一步是从起点开始的,而选择起点的过程不能算做一步。
代码如下:
I used to think I could be anything, but now I know that I couldn't do anything. So I started traveling.
The
nation looks like a connected bidirectional graph, and I am randomly
walking on it. It means when I am at node i, I will travel to an
adjacent node with the same probability in the next step. I will pick up
the start node randomly (each node in the graph has the same
probability.), and travel for d steps, noting that I may go through some
nodes multiple times.
If I miss some sights at a node, it will
make me unhappy. So I wonder for each node, what is the probability that
my path doesn't contain it.
[align=left]Input[/align]
The first line contains an integer T, denoting the number of the test cases.
For
each test case, the first line contains 3 integers n, m and d, denoting
the number of vertices, the number of edges and the number of steps
respectively. Then m lines follows, each containing two integers a and
b, denoting there is an edge between node a and node b.
T<=20,
n<=50, n-1<=m<=n*(n-1)/2, 1<=d<=10000. There is no
self-loops or multiple edges in the graph, and the graph is connected.
The nodes are indexed from 1.
[align=left]Output[/align]
For each test cases, output n lines, the i-th line containing the desired probability for the i-th node.
Your answer will be accepted if its absolute error doesn't exceed 1e-5.
[align=left]Sample Input[/align]
2
5 10 100
1 2
2 3
3 4
4 5
1 5
2 4
3 5
2 5
1 4
1 3
10 10 10
1 2
2 3
3 4
4 5
5 6
6 7
7 8
8 9
9 10
4 9
[align=left]Sample Output[/align]
0.0000000000
0.0000000000
0.0000000000
0.0000000000
0.0000000000
0.6993317967
0.5864284952
0.4440860821
0.2275896991
0.4294074591
0.4851048742
0.4896018842
0.4525044250
0.3406567483
0.6421630037
题目大意:给一张无根无向图(n个节点,m条边),每一步走哪一个儿子节点的概率相同(以哪个点为起点的概率也相同)。对于每个点,找出走完d步后走不到该点的概率。
题目分析:定义dp(s,u)表示不经过节点i(1<=i<=n)走了s步时,到达u点的概率。则根据加法原理,dp(s,son)=sum(dp(s-1,u)*f),其中 f 是u走到其儿子son的概率,f=1.0/(u的儿子个数)。题目要求分别输出不经过节点 i (1<=i<=n) 的答案,则DP n次即可。对于每次DP,根据加法原理,答案为ans=sum(dp(d,j)),其中,j不等于i。
注意:第一步是从起点开始的,而选择起点的过程不能算做一步。
代码如下:
# include<iostream> # include<cstdio> # include<vector> # include<cstring> # include<algorithm> using namespace std; vector<int>v[55]; int n,m,d,vis[10005][55]; double dp[10005][55]; void solve() { for(int i=1;i<=n;++i){ memset(dp,0,sizeof(dp)); for(int j=1;j<=n;++j) dp[0][j]=1.0/n; for(int j=1;j<=d;++j){ for(int start=1;start<=n;++start){ if(i==start) continue; int l=v[start].size(); for(int k=0;k<l;++k) dp[j][v[start][k]]+=dp[j-1][start]*1.0/l; } } double ans=0.0; for(int j=1;j<=n;++j) if(j!=i) ans+=dp[d][j]; printf("%.10lf\n",ans); } } int main() { int T,a,b; vector<int>::iterator it; scanf("%d",&T); while(T--) { memset(vis,0,sizeof(vis)); scanf("%d%d%d",&n,&m,&d); for(int i=1;i<=n;++i) v[i].clear(); while(m--) { scanf("%d%d",&a,&b); it=find(v[a].begin(),v[a].end(),b); if(it==v[a].end()) v[a].push_back(b); it=find(v[b].begin(),v[b].end(),a); if(it==v[b].end()) v[b].push_back(a); } solve(); } return 0; }
相关文章推荐
- js懒人工具包
- 【Linux】bridge-utils brctl 网桥配置命令
- VS代码文件中添加协议格式
- 取出现次数最多的K个数
- 纯CSS定义input file样式及上传图片预览 CSS
- Java设计模式-代理模式
- Codeforces Codeforces Round #319 (Div. 2) B. Modulo Sum 背包dp
- Java设计模式-代理模式
- Windows 7中,用Visual Studio开发WPF应用程序,实现从Windows Explorer中拖拽文件到应用程序,始终显示“无法拖放”符号问题解决方案
- 笔记03 MVVM 开发的几种模式(WPF)
- Who-are-the-top-Java-experts-in-the-world
- MySQL通用优化技巧
- 一分钟看懂外卖O2O:小心!别掉入这三个坑里
- CentOS6下安装Java jdk1.7.0_10
- 记一次基于Unity的Profiler性能分析
- Android问题集锦之三十八:not allowed to send broadcast android.intent.action.MEDIA_MOUNTED
- MDCT/MDST, IMDCT与DCT-IV的关系以及快速FFT实现
- java多线程模拟停车位问题
- bzoj1607:轻拍牛头
- MySQL通用优化技巧