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 long
const 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-10
int 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;
}
}