比赛的时候一直不知道样例怎么来的,然后和队友推了一下,然后还是没什么思路,样例手推很困难,然后我随口枚举了几个算法dp、广搜、快速幂。比赛结束问了谷队长结果真的是用快速幂写。
题意:n个点,m条边,每一步可以从一个点走到与其相连的点上,求如果最多可以走T步,1到n有多少种走法。
思路:裸的矩阵快速幂,初始矩阵在输入的时候连的双向边,表示可走,但要注意从n出发的话只有单向边,题目说明走到n号节点就不能走出去了。n到n也要连一条边。然后求这个矩阵的T次方,结果就是第一行第n列的值。
int n,m,t;
struct matrix
{
ll a[101][101];
};
matrix mul(matrix A,matrix B)
{
matrix res;
memset(res.a,0,sizeof(res.a));
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
for(int k=1;k<=n;k++)
res.a[i][j]=(res.a[i][j]+A.a[i][k]*B.a[k][j])%MOD;
return res;
}
matrix mul_pow(matrix A)
{
matrix res;
memset(res.a,0,sizeof(res.a));
for(int i=1;i<=n;i++) res.a[i][i]=1;
while(t)
{
if(t&1) res=mul(res,A);
A=mul(A,A);
t>>=1;
}
return res;
}
void solve()
{
int u,v;
matrix res;
for(int i=0; i<m; i++)
{
scanf("%d%d",&u,&v);
if(u==n) res.a[v][u]=1;
else if(v==n) res.a[u][v]=1;
else res.a[u][v]=res.a[v][u]=1;
}
res.a[n][n]=1;
scanf("%d",&t);
res=mul_pow(res);
printf("%lld\n",res.a[1][n]);
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
solve();
}
return 0;
}