• [题解]luogu_P2151_HH去散步(矩阵floyd


    此题似乎有两种写法,一种是一维表示步数,一维表示边,一种是两维都表示边,类似floyd,这里是第二种

    这题和裸矩阵floyd唯一的区别就是不能从上一次来的边走回去,

    如果还像原来一样用点表示状态就信息不足,暂且不考虑矩快优化dp的问题,要想知道上回走的那条边不如干脆记录上回走的哪条边,这样不仅知道从哪条边走来,因为边确定了现在在哪个点也确定了,所以设$f[i][j]$为从编号为$i$的边走到编号为$j$的边的路径数,然后直接矩快即可,注意0时刻没走,矩阵全是0没法转移,所以初始时相当于已经走出一步走了一条边了,只要$t-1$次幂即可

    注意边的编号从2开始

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=55;
    const int maxm=65;
    const int mod=45989;
    inline int read(){
        int ret=0,fix=1;char ch;
        while(!isdigit(ch=getchar()))fix=ch=='-'?-1:fix;
        do ret=(ret<<1)+(ret<<3)+ch-'0';
        while(isdigit(ch=getchar()));
        return ret*fix;
    }
    int n,m,t,aa,bb;
    struct node{
        int v,nxt;
    }e[maxm<<1];
    int head[maxn],cnt=1;
    inline void add(int u,int v){
        e[++cnt].v=v;e[cnt].nxt=head[u];head[u]=cnt;
    }
    struct mat{
        int a[200][200];
    //    mat(){}
        void clear(){
            memset(a,0,sizeof(a));
        }
    }f;
    mat operator *(mat t1,mat t2){
        mat ans;ans.clear();
        for(int i=1;i<=m*2;i++)
        for(int j=1;j<=m*2;j++)
        for(int k=1;k<=m*2;k++)
        ans.a[i][j]=(ans.a[i][j]+t1.a[i][k]*t2.a[k][j])%mod;
        return ans;
    }
    mat operator^(mat a,int b){
        mat ans;ans.clear();
        for(int i=1;i<=m*2;i++)ans.a[i][i]=1;
        while(b){
            if(b&1)ans=ans*a;
            a=a*a;
            b>>=1;
        }
        return ans;
    }
    int main(){
        scanf("%d%d%d%d%d",&n,&m,&t,&aa,&bb);aa++,bb++;
        for(int i=1,u,v;i<=m;i++){
            u=read();v=read();u++,v++;
            add(u,v);add(v,u);
        }
        for(int i=2;i<=m*2+1;i++){
            for(int j=head[e[i].v];j;j=e[j].nxt){
                if(j!=(i^1))f.a[i-1][j-1]=1;
            }
        }
        f=f^(t-1);
        int cnt=0;
        for(int i=head[aa];i;i=e[i].nxt)
        for(int j=2;j<=m*2+1;j++)
        if(e[j].v==bb)(cnt+=f.a[i-1][j-1])%=mod;
        printf("%d",cnt);
        
    }
  • 相关阅读:
    第一周作业
    C语言I博客作业08
    十四周助教总结
    十三周助教总结
    C语言I博客作业07
    C语言II博客作业01
    学期总结
    C语言I博客作业08(未完成)
    C语言I博客作业07
    C语言I博客作业06
  • 原文地址:https://www.cnblogs.com/superminivan/p/11508541.html
Copyright © 2020-2023  润新知