题解:
发现总的周期是
,先用
求出走
步的情况,然后用矩阵乘法处理。
对于剩下的步数,直接暴力
即可。
#include<iostream>
#include<cstdio>
#include<cstring>
#define mod 10000
using namespace std;
int n,m,fish,start,end,T,t[25],f[25][5];
int cnt,ans[55],head[55],a[15][55][55],b[55][55];
struct node
{
int vet,next;
}e[10005];
void add(int u,int v)
{
e[++cnt].vet=v;
e[cnt].next=head[u];
head[u]=cnt;
}
void build1(int x)
{
for(int i=head[x];i;i=e[i].next)
for(int j=1;j<=12;j++)
a[j][x][e[i].vet]=1;
}
void build2(int x)
{
for(int i=1;i<=12;i++)
{
int tmp=f[x][i%t[x]];
for(int j=0;j<n;j++)
a[i][j][tmp]=0;
}
}
void mul1(int a[55][55],int b[55][55],int c[55][55])
{
int tmp[55][55];
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
{
tmp[i][j]=0;
for(int k=0;k<n;k++)
tmp[i][j]=(tmp[i][j]+a[i][k]*b[k][j])%mod;
}
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
c[i][j]=tmp[i][j];
}
void mul2(int a[55],int b[55][55],int c[55])
{
int tmp[55];
for(int j=0;j<n;j++)
{
tmp[j]=0;
for(int k=0;k<n;k++)
tmp[j]=(tmp[j]+a[k]*b[k][j])%mod;
}
for(int j=0;j<n;j++)c[j]=tmp[j];
}
int main()
{
scanf("%d%d%d%d%d",&n,&m,&start,&end,&T);
for(int i=1;i<=m;i++)
{
int u,v;
scanf("%d%d",&u,&v);
add(u,v);add(v,u);
}
scanf("%d",&fish);
for(int i=1;i<=fish;i++)
{
scanf("%d",&t[i]);
for(int j=0;j<t[i];j++)
scanf("%d",&f[i][j]);
}
for(int i=0;i<n;i++)build1(i);
for(int i=1;i<=fish;i++)build2(i);
for(int i=0;i<n;i++)
b[i][i]=a[13][i][i]=1;
for(int i=1;i<=12;i++)
mul1(a[13],a[i],a[13]);
int tmp=T/12;
while(tmp)
{
if(tmp&1)mul1(b,a[13],b);
mul1(a[13],a[13],a[13]);
tmp>>=1;
}
for(int i=1;i<=T%12;i++)mul1(b,a[i],b);
ans[start]=1;
mul2(ans,b,ans);
printf("%d",ans[end]);
return 0;
}