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

来源:互联网 发布:mac jenkins 使用教程 编辑:程序博客网 时间:2024/05/21 08:51

大意:给定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 __int64using 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;}
0 0
原创粉丝点击