Description
加里敦星球的人们特别喜欢喝可乐。因而,他们的敌对星球研发出了一个可乐机器人,并且
放在了加里敦星球的1号城市上。这个可乐机器人有三种行为:停在原地,去下一个相邻的
城市,自爆。它每一秒都会随机触发一种行为。现在给出加里敦星球城市图,在第0秒时可
乐机器人在1号城市,问经过了t秒,可乐机器人的行为方案数是多少?
Input
第一行输入两个正整数N,M表示城市个数,M表示道路个数。(1≤N≤30,0≤M≤100) 接下来M行输入u,v表示u,v之间有一条道路。
(1≤u,v≤n)保证两座城市之间只有一条路相连。 最后输入时间t。1< t≤10^6
Output
输出可乐机器人的行为方案数,答案可能很大,请输出对2017取模后的结果。
Sample Input
3 2
1 2
2 3
2
Sample Output
8
题解
这种图论求方案数图又那么小的当然矩乘啊
一开始复杂度搞错了以为是9kw的实际上是9e..然后果断敲了个暴力稳定T
由于会自爆,所以每一次矩乘都要统计一下sum
那你直接在初始矩阵末尾加一个和就ok了嘛
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
const int mod=2017;
int n,m,ans,T;
struct matrix
{
int m[35][35];
matrix(){memset(m,0,sizeof(m));}
}st,tmp,cnt;
matrix mul(matrix u,matrix v,int n,int m,int p)
{
matrix ret;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
for(int k=1;k<=p;k++)
ret.m[i][k]=(ret.m[i][k]+u.m[i][j]*v.m[j][k])%mod;
return ret;
}
matrix pow_mod(matrix u,int b)
{
matrix ans;
for(int i=1;i<=n+1;i++)ans.m[i][i]=1;
while(b)
{
if(b&1)ans=mul(ans,u,n+1,n+1,n+1);
u=mul(u,u,n+1,n+1,n+1);b>>=1;
}
return ans;
}
struct node
{
int x,y,next;
}a[210];int len,last[110];
void ins(int x,int y)
{
len++;
a[len].x=x;a[len].y=y;
a[len].next=last[x];last[x]=len;
}
int main()
{
scanf("%d%d",&n,&m);
len=0;memset(last,0,sizeof(last));
for(int i=1;i<=m;i++)
{
int x,y;scanf("%d%d",&x,&y);
ins(x,y);ins(y,x);
}
st.m[1][1]=1;
for(int i=1;i<=n;i++)
{
for(int k=last[i];k;k=a[k].next)tmp.m[a[k].y][i]=1;
tmp.m[i][i]=1;
tmp.m[i][n+1]=1;
}
tmp.m[n+1][n+1]=1;
scanf("%d",&T);
tmp=pow_mod(tmp,T+1);
st=mul(st,tmp,1,n+1,n+1);
/* for(int i=1;i<=T;i++)
{
st=mul(st,tmp,1,n,n);
for(int i=1;i<=n;i++)ans=(ans+st.m[1][i])%mod;
}*/
printf("%d\n",st.m[1][n+1]);
return 0;
}