一眼矩乘
把图分成12个,然后直接搞。
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> using namespace std; typedef long long LL; const LL mod=10000; int n; struct Matrix { LL a[60][60]; Matrix(){} void clean() { memset(a,0,sizeof(a)); } void beone() { clean(); for(int i=1;i<=n;i++)a[i][i]=1; } friend Matrix operator *(Matrix A,Matrix B) { Matrix C;C.clean(); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) for(int k=1;k<=n;k++) C.a[i][j]=(C.a[i][j]+(A.a[i][k]*B.a[k][j])%mod)%mod; return C; } }G[12]; LL mp[60][60]; int main() { freopen("swamp.in","r",stdin); freopen("swamp.out","w",stdout); int m,st,ed,x,y;LL K; scanf("%d%d%d%d%lld",&n,&m,&st,&ed,&K);st++,ed++; memset(mp,0,sizeof(mp)); for(int i=1;i<=m;i++) { scanf("%d%d",&x,&y);x++,y++; mp[x][y]=1;mp[y][x]=1; } for(int k=0;k<=11;k++) for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) G[k].a[i][j]=mp[i][j]; int fish;LL p; scanf("%d",&fish); for(int i=1;i<=fish;i++) { scanf("%lld",&p); for(int j=1;j<=p;j++) { scanf("%d",&x);x++; for(int k=j-1;k<=11;k+=p) { for(int u=1;u<=n;u++)G[k].a[u][x]=0; } } } Matrix YZH;YZH.beone(); for(int i=1;i<=12;i++) { YZH=YZH*G[i%12]; if(K==i){printf("%lld\n",YZH.a[st][ed]);return 0;} } p=K/12;K%=12; Matrix ans;ans.beone(); while(p!=0) { if(p%2==1)ans=ans*YZH; YZH=YZH*YZH;p/=2; } for(int i=1;i<=K;i++)ans=ans*G[i]; printf("%lld\n",ans.a[st][ed]); return 0; }