题目
解说
裸矩阵快速幂,没啥可说的。
下面再附上(gyz)大佬的超级快的(DP)做法。
代码
矩阵快速幂:
#include<bits/stdc++.h>
using namespace std;
const int mod = 1000;
struct ju{
int ar[25][25];
ju(){memset(ar,0,sizeof(ar));}
};
int n,m;
ju cheng(ju a,ju b){
ju ans;
for(int k=0;k<n;++k){
for(int i=0;i<n;++i){
for(int j=0;j<n;++j){
ans.ar[i][j]+=a.ar[i][k]*b.ar[k][j];
ans.ar[i][j]%=mod;
}
}
}
return ans;
}
ju power(ju a,int b){
ju ret;
for(int i=0;i<n;++i){
for(int j=0;j<n;++j){
ret.ar[i][j]=(i==j);
}
}
while(b>0){
if(b&1)ret=cheng(ret,a);
a=cheng(a,a);
b>>=1;
}
return ret;
}
int main(){
while(1){
scanf("%d%d",&n,&m);
if(m==0&&n==0) return 0;
ju a,b;
memset(a.ar,0,sizeof(a.ar));
while(m--){
int u,v;scanf("%d%d",&u,&v);
a.ar[u][v]=1;
}
int t,x,y,k;
scanf("%d",&t);
while(t--){
scanf("%d%d%d",&x,&y,&k);
b=power(a,k);
printf("%d
",b.ar[x][y]);
}
}
}
DP:
#include<cstdio>
#include<cstring>
#include<algorithm>
const int N=11+10;
int dis[N][N],to[N][N];
int main(){
int n,m;
while(~scanf("%d%d",&n,&m)){
if(n==0&&m==0)return 0;
memset(to,0,sizeof(to));
for(int i=1;i<=m;i++){
int a,b;
scanf("%d%d",&a,&b);
to[a][b]=1;
}
int T;
scanf("%d",&T);
while(T--){
int a,b,k;
memset(dis,0,sizeof(dis));
scanf("%d%d%d",&a,&b,&k);
dis[0][a]=1;
for(int x=1;x<=k;x++){
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(to[i][j])
dis[x][j]=(dis[x][j]+dis[x-1][i])%1000;
}
}
}
printf("%d
",dis[k][b]);
}
}
}
幸甚至哉,歌以咏志。