2014區域網絡賽鞍山校區上的第五題:
Walk
Time Limit: 30000/15000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 183 Accepted Submission(s): 127
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.
正解應該是剛開始每個點1/n的初始概率,然後刪除I點,之後求出其餘點能走到的概率,能走到的概率總和即I點不能走到的概率,然後注意到任意兩點直接走到的概率可以形成一個矩陣,走了d步相當於初始概率形成的矩陣*概率矩陣^d。 故可以用矩陣快速冪來做。
由於時限較寬,其餘方法還有很多,若暫時看不懂本題含義,可以先去看這道題的概率DP題解,其實思想是一樣的。
代碼:
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<ctime>
#include<string>
#include<cstring>
#include<algorithm>
#include<fstream>
#include<queue>
#include<stack>
#include<vector>
#include<cmath>
#include<iomanip>
#define rep(i,n) for(i=1;i<=n;i++)
#define MM(a,t) memset(a,t,sizeof(a))
#define INF 1e9
typedef long long ll;
#define mod 1000000007
using namespace std;
int n,m,d;
vector<int> eg[100];
struct matrix{
double a[100][100];
}pan,st,npan;
matrix mul(matrix a1,matrix a2,int i1,int i2){
int i,j,k;
matrix c;
rep(i,i1)
rep(j,i2){
c.a[i][j]=0;
rep(k,i2){
c.a[i][j]+=a1.a[i][k]*1.0*a2.a[k][j];
}
}
return c;
}
void qmi(int nn){
int j,k;
while(nn){
if(nn%2==1) st=mul(st,npan,1,n);
npan=mul(npan,npan,n,n);
nn=(nn>>1);
}
}
int main()
{
int i,j,k,T;
scanf("%d",&T);
while(T--){
scanf("%d%d%d",&n,&m,&d);
rep(i,n) eg[i].clear();
MM(pan.a,0);
rep(i,m){
int s,e;
scanf("%d%d",&s,&e);
eg[s].push_back(e);
eg[e].push_back(s);
}
rep(i,n){
int sz=eg[i].size();
for(j=0;j<sz;j++) pan.a[i][eg[i][j]]=1.0/sz;
}
rep(i,n){
double res=0;
rep(j,n) st.a[1][j]=1.0/n;
MM(npan.a,0);
rep(j,n)
rep(k,n)
if(j!=i && k!=i) npan.a[j][k]=pan.a[j][k];
qmi(d);
rep(j,n) res+=st.a[1][j];
printf("%.8lf\n",res);
}
}
return 0;
}