大意:给定n个点,然后个关系代表x到y之间有有向路,问从s到t之间经过k个点(即k步),有多少种方式。
思路:存在一条边i->j。令C=A*A,那么C(i,j)=ΣA(i,k)*A(k,j),一条边乘一次,k条即乘k次。
#include<map>
#include<cmath>
#include<queue>
#include<cmath>
#include<cstdio>
#include<stack>
#include<iostream>
#include<cstring>
#include<algorithm>
#define inf 0x3f3f3f3f
#define eps 1e-8
#define ls l,mid,rt<<1
#define rs mid+1,rt,rt<<1|1
#define LL __int64
using namespace std;
const int mod = 1000;
int n;
struct node{
int r[100][100];
}q,now;
node matrix_pow(node a,node b){
int i,j,k;
node t;
memset(t.r,0,sizeof(t.r));
for(k = 1;k <= n;++ k){
for(i =1 ;i <= n;i++){
for(j = 1;j <= n;++ j){
t.r[i][j] = (t.r[i][j]+ (a.r[i][k]*b.r[k][j]))%mod;
}
}
}
return t;
}
node so(node q,int m){
int i,j,k;
node tmp;
memset(tmp.r,0,sizeof(tmp.r));
for(i = 1;i <= n;++ i )
tmp.r[i][i] = 1;
while(m){
if(m&1)
tmp = matrix_pow(tmp,q);
q = matrix_pow(q,q);
m = m >> 1;
}
return tmp;
}
int main(){
int m,k,i,j,x,y,s,t,poi;
while(~scanf("%d%d",&n,&m)){
if(!n&&!m)
break;
memset(q.r,0,sizeof(q.r));
for(i = 0;i < m; ++i){
scanf("%d%d",&x,&y);
q.r[++x][++y] = 1;
}
now = q;
scanf("%d",&k);
while(k --){
scanf("%d%d%d",&s,&t,&poi);
q = so(now,poi);
printf("%d\n",q.r[++s][++t]%mod);
}
}
return 0;
}
本文介绍了一种使用矩阵快速幂算法解决特定图论问题的方法,即计算从起点到终点经过固定步数的不同路径数量。通过定义邻接矩阵并利用快速幂运算,有效地解决了这一问题。
4万+

被折叠的 条评论
为什么被折叠?



