BZOJ1898-[Zjoi2005]Swamp 沼泽鳄鱼


题解:
发现总的周期是 12 12 ,先用 dp d p 求出走 12 12 步的情况,然后用矩阵乘法处理。
对于剩下的步数,直接暴力 dp d p 即可。
Code: 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; 
} 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jack-Oran

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值