Walk
Time Limit: 30000/15000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 350 Accepted Submission(s): 228
Special Judge
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.
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.
Your answer will be accepted if its absolute error doesn't exceed 1e-5.
題意:求走d步不經過i點的概率。
思路:這題題解是矩陣快速冪的做法,但是概率dp也可以,dp[d][i]表示走d步到達i點的概率,每次排除一點,求所有點的概率和就是不經過該點的概率。求概率這種東西一般就是變換思維,比賽的時候思路沒繞過來,就想不明白怎麼求概率。
#include <iostream>
#include <stdio.h>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
const int mod=1e9+7;
const int N=52;
vector <int> vec[N];
int t,n,m,d,a,b;
double dp[10005][N],ans[N];
void init(){
memset(ans,0,sizeof(ans));
memset(vec,0,sizeof(vec));
scanf("%d%d%d",&n,&m,&d);
while(m--){
scanf("%d%d",&a,&b);
vec[a].push_back(b);
vec[b].push_back(a);
}
}
void solve(){
for(int cas=1;cas<=n;cas++){
memset(dp,0,sizeof(dp));
for(int i=1;i<=n;i++)
dp[0][i]=1.0/n;
dp[0][cas]=0;
for(int i=1;i<=d;i++){
for(int j=1;j<=n;j++){
if(j==cas)continue;
for(int k=0;k<vec[j].size();k++){
if(vec[j][k]==cas)continue;
dp[i][j]+=dp[i-1][vec[j][k]]/vec[vec[j][k]].size();
}
}
}
for(int i=1;i<=n;i++)
ans[cas]+=dp[d][i];
}
for(int i=1;i<=n;i++)printf("%.8lf\n",ans[i]);
}
int main()
{
scanf("%d",&t);
while(t--){
init();
solve();
}
return 0;
}