BZOJ1898-[Zjoi2005]Swamp 沼泽鳄鱼


题解:
发现总的周期是 12 ,先用 d p 求出走 12 步的情况,然后用矩阵乘法处理。
对于剩下的步数,直接暴力 d p 即可。
C o d e :

#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; 
} 


猜你喜欢

转载自blog.csdn.net/qq_34531807/article/details/81050770
今日推荐