链接
题目描述
加里敦星球的人们特别喜欢喝可乐。因而,他们的敌对星球研发出了一个可乐机器人,并且放在了加里敦星球的 1 号城市上。这个可乐机器人有三种行为:停在原地,去下一个相邻的城市,自爆。它每一秒都会随机触发一种行为。现在给出加里敦星球城市图,在第 0 秒时可乐机器人在 1 号城市,问经过了 t 秒,可乐机器人的行为方案数是多少?
思路
构建邻接矩阵,答案就是这个矩阵的t次方的每一项之和,直接用快速幂加速就好了
自爆就连个0号点,然后留在原地就是每个点连个自环就好了
代码
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#define ll long long
using namespace std;
const ll mo = 2017;
ll n, m, t, u, v, Ans;
struct matrix
{
int n, m;
ll a[105][105];
}g, ans;
matrix operator *(matrix a, matrix b)
{
matrix c;
c.n = a.n;
c.m = b.m;
memset(c.a, 0, sizeof(c.a));
for(int k = 0; k <= a.m; ++k)
for(int i = 0; i <= c.n; ++i)
for(int j = 0; j <= c.m; ++j)
c.a[i][j] = (c.a[i][j] + (a.a[i][k] * b.a[k][j]) % mo);
return c;
}
void ksm(ll t)
{
memset(ans.a, 0, sizeof(ans.a));
for(int i = 0; i <= ans.n; ++i)
ans.a[i][i] = 1;
while(t)
{
if(t & 1) ans = ans * g;
g = g * g;
t >>= 1;
}
}
int main()
{
scanf("%lld%lld", &n, &m);
for(int i = 1; i <= m; ++i)
{
scanf("%lld%lld", &u, &v);
g.a[u][v] = g.a[v][u] = 1;
}
g.n = g.m = n;
ans.n = ans.m = n;
for(int i = 0; i <= n; ++i)
g.a[i][i] = 1;
for(int i = 1; i <= n; ++i)
g.a[i][0] = 1;
scanf("%lld", &t);
ksm(t);
for(int i = 0; i <= n; ++i)
Ans = (ans.a[1][i] + Ans) % mo;
printf("%lld", Ans % mo);
return 0;
}