武大校赛E题

来源:互联网 发布:低级格式化数据恢复 编辑:程序博客网 时间:2024/05/01 12:29

E. Lost in WHU

题意是给定一副无向图,然后求走了T步之内,从起点到终点有多少走法,(有个地方题面没有说清楚,就是走到点n之后不能再往别的点走了)

邻接矩阵,乘T次之后,MAP[i][j]就是从i点走到j点的且走T步时的走法。
我们把矩阵中n到其他点的路径去掉,
所以我们要算的就是∑ (Map[1][n] )^i (1 <= i <= T)就是答案了 。于是我们要构造一个矩阵把前缀和记录一下。
由于在原来的邻接矩阵中,我们只关心的只有Map[1][n]这个值,我们可以把原矩阵放入一个新的矩阵中,或者说把矩阵拓展一维,令Map[0][n] = 1,然后把这样,Map[1][0]记录的就是上一个状态的Map[1][n],由于是要求前缀和,我们要把他再加起来,所以Map[0][0]处再添加一个1进去,这样就可以把上个状态一起加进去,递推之后Map[1][0]就是不包括当前状态前缀和,最后答案就是Map[1][n] + Map[1][0] ;

#include<cmath>#include<algorithm>#include<cstring>#include<string>#include<set>#include<map>#include<time.h>#include<cstdio>#include<vector>#include<stack>#include<queue>#include<iostream>using namespace std;#define  LONG long longconst int   INF=0x3f3f3f3f;const LONG    MOD=1e9+7;const double PI=acos(-1.0);#define clr0(x) memset(x,0,sizeof x)#define clrI(x) memset(x,-1,sizeof(x))#define clr1(x) memset(x,INF,sizeof x)#define clr2(x) memset(x,-INF,sizeof x)#define EPS 1e-10int n ;struct Matr{    LONG matr[120][120];    Matr(LONG  x = 0)    {        for(int i = 0; i <= 110 ;++i)            for(int j =0; j <= 110 ;++ j)matr[i][j] = x;    }    Matr ( LONG x,int y)    {        clr0(matr);        for(int i = 0 ; i <= y ; ++ i)matr[i][i] = x ;    }};Matr operator * (Matr &a , Matr &b){    Matr ans (0);    for(int i = 0 ; i<= n ; ++ i)    {        for(int j =0; j<= n ; ++ j)            for(int k = 0; k <= n ;++ k)        ans.matr[i][j] = (ans.matr[i][j] +  a.matr[i][k] * b.matr[k][j] ) % MOD;    }    return ans ;}Matr Equ(Matr &a , Matr &b){    for(int i =0; i<=n ;++ i)        for(int j =0; j<= n ;++ j)a.matr[i][j] = b.matr[i][j];    return a;}Matr Q_pow_M( Matr &a , LONG b){    Matr res(1 , n);    while(b)    {        if(b & 1)            res = res * a ;        a = a * a;        b /= 2;    }    return res ;}int main(){//freopen("C:\\Users\\ZhangYuyang\\Desktop\\in.txt","r",stdin);//freopen("C:\\Users\\ZhangYuyang\\Desktop\\out1.txt","w",stdout);    int m;    while(~scanf("%d%d",&n,&m))    {    Matr take(0) ;    take.matr[0][0] = 1 , take.matr[n][0] = 1 ;    for(int i =1; i<= m ;++ i)    {        int a, b;        scanf("%d%d",&a,&b);        if(a != n)        take.matr[a][b] = 1;        if(b != n )        take.matr[b][a] = 1;    }    int T ;    cin>> T ;    Matr tmp(0);    Matr ans(0);    ans = Q_pow_M( take , T  ) ;    cout<<( ans.matr[1][n] + ans.matr[1][0] ) % MOD<<endl ;    LONG sum = 0;    }}
1 0