graph HDU - 5607
In a directed graph which has N points and M edges,points are labled from 1 to n.At first I am at point u,at each step I will choose an output edge of the current point at uniform random,for every point Z,please output the possibility of reaching the point Z,moving exactly K
steps.
Input
the first line contains two positive intergesN,M,means the number of points and edges.
next M lines,contains two positive intergersX,Y,means an directed edge from X to Y.
next line there is an integer Q,means the number of queries.
next Q lines,each line contains two integers u,K,means the first point and number of the steps.
N≤50,M≤1000,Q≤20,u≤N,K≤109
.
Every point have at least one output edge.
Output
Q lines,each line contains N numbers,the i-th number means the possibility of reaching point i from u,moving exactly K steps.
In consideration of the precision error,we make some analyses,finding the answer can be represented as the form like XY,you only need to output X×Y109+5 mod (109+7)
.
You need to output an extra space at the end of the line,or you will get PE.
Sample Input
3 2
1 2
1 3
1
1 1
Sample Output
0 500000004 500000004
I am now at point $1$,by one move,with a possibity of $\frac{1}{2}$ of reaching point 2,with a possibity of $\frac{1}{2}$ of reaching point 3,so we need to output 0 0.5 0.5,but as what is said above,we need to output$1*2^{10^9+5}~mod~{10^9+7}=500000004$.
分析:
实际上题目就是求K步可达路径,直接矩阵快速幂即可,只不过这里初始矩阵中存的不是0,1而是概论
即 原来a[i][j]表示i可以到达j则为1,现在a[i][j]=1out[i]其中out[i]表示i点的出度,那么此时就变成了从i点到达j点的概率 原 来 a [ i ] [ j ] 表 示 i 可 以 到 达 j 则 为 1 , 现 在 a [ i ] [ j ] = 1 o u t [ i ] 其 中 o u t [ i ] 表 示 i 点 的 出 度 , 那 么 此 时 就 变 成 了 从 i 点 到 达 j 点 的 概 率
然后直接矩阵快速幂即可,注意输出格式很无聊
最后一行有空格,而且每次询问中间隔一行
code:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod = 1e9+7;
const int N = 60;
struct Matrix{
ll m[N][N];
};
int n,m;
ll out[N];
Matrix mul(Matrix a,Matrix b){
Matrix ans;
for(int i = 1; i <= n; i++){
for(int j = 1; j <= n; j++){
ans.m[i][j] = 0;
for(int k = 1; k <= n; k++){
ans.m[i][j] = (ans.m[i][j] + a.m[i][k] * b.m[k][j] % mod) % mod;
}
}
}
return ans;
}
Matrix mq_pow(Matrix a,ll b){
Matrix ans;
memset(ans.m,0,sizeof(ans.m));
for(int i = 1; i <= n; i++){
ans.m[i][i] = 1;
}
while(b){
if(b & 1)
ans = mul(ans,a);
b >>= 1;
a = mul(a,a);
}
return ans;
}
ll q_pow(ll a,ll b){
ll ans = 1;
while(b){
if(b & 1)
ans = ans * a % mod;
b >>= 1;
a = a * a % mod;
}
return ans;
}
int main(){
while(~scanf("%d%d",&n,&m)){
memset(out,0,sizeof(out));
Matrix a;
memset(a.m,0,sizeof(a.m));
for(int i = 1; i <= m; i++){
int x,y;
scanf("%d%d",&x,&y);
out[x]++;
a.m[x][y] = 1;
}
for(int i = 1; i <= n; i++){
for(int j = 1; j <= n; j++){
if(a.m[i][j]){
a.m[i][j] = q_pow(out[i],mod-2);
}
}
}
int q;
scanf("%d",&q);
while(q--){
int u,K;
scanf("%d%d",&u,&K);
Matrix ans = mq_pow(a,K);
for(int i = 1; i <= n; i++){
printf("%lld ",ans.m[u][i]);
}
puts("");
}
}
return 0;
}