HDU 2157 How many ways??(矩阵快速幂)

大意:给定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;
}

你可能感兴趣的:(矩阵快速幂)