HDU 2157

http://acm.hdu.edu.cn/showproblem.php?pid=2157

求A到B经过K个点的方案数

http://www.matrix67.com/blog/archives/276  这里面的经典问题8

存图的邻接矩阵自乘k次,得到的新矩阵A行B列就是答案

#include <iostream> 

#include <cstdio>

#include <cstring>

using namespace std ;



#define Matr 105 //矩阵大小,注意能小就小  

  

struct mat//矩阵结构体,a表示内容,r行c列 矩阵从1开始  

{  

    int a[Matr][Matr];

    int r,c;  

    mat()  

    {  

        r=c=0;  

        memset(a,0,sizeof(a));  

    }  

};  

void print(mat m)

{  

    int i,j;  

    //printf("%d\n",m.size);  

    for(i=0;i<m.r;i++)  

    {  

        for(j=0;j<m.c;j++)printf("%d ",m.a[i][j]);  

        printf("\n");  

    }  

}  

  

mat mul(mat m1,mat m2,int mod)

{  

    mat ans=mat();ans.r=m1.r;ans.c=m2.c;  

    for(int i=1;i<=m1.r;i++)  

        for(int j=1;j<=m2.r;j++)  

            if(m1.a[i][j])

                for(int k=1;k<=m2.c;k++)  

                    ans.a[i][k]=(ans.a[i][k]+m1.a[i][j]*m2.a[j][k])%mod;  

    return ans;  

}  

mat quickmul(mat m,int n,int mod)

{  

    mat ans=mat();  

    int i;  

    for(i=1;i<=m.r;i++)ans.a[i][i]=1;  

    ans.r=m.r;ans.c=m.c;  

    while(n)  

    {  

        if(n&1)ans=mul(m,ans,mod);  

        m=mul(m,m,mod);  

        n>>=1;  

    }  

    return ans;  

}  

/* 

ans^=n -> 

mat ans=mat(); 

ans.r=R;ans.c=C; 

初始化ans矩阵 

ans=quickmul(ans,n,mod); 

*/  



int main()

{

    int n,m ;

    while(~scanf("%d%d",&n,&m))

    {

        if(!n && !m)break ;

        mat M=mat() ;

        M.r=n ;M.c=n ;        

        while(m--)

        {

            int a,b ;

            scanf("%d%d",&a,&b) ;

            M.a[a+1][b+1]=1 ;

        }

        int T ;

        scanf("%d",&T) ;

        while(T--)

        {

            int a,b,k ;

            scanf("%d%d%d",&a,&b,&k) ;

            mat res=quickmul(M,k,1000) ;

            printf("%d\n",res.a[a+1][b+1]) ;

        }

    }

    return 0 ;

}
View Code

 

你可能感兴趣的:(HDU)