zoukankan      html  css  js  c++  java
  • Luogu P3758 [TJOI2017]可乐 | 矩阵乘法

    题目链接

     

    让我们先来思考一个问题,在一张包含$n$个点的图上,如何求走两步后从任意一点$i$到任意一点$j$的方案数。

    我们用$F_p(i,j)$来表示走$p$步后从$i$到$j$的方案数,如果存储原图信息的是一个邻接矩阵$G$,那么显然就有:

    $F_1(i,j)=G(i,j)$

    $F_2(i,j)=sum_{k=1}^n G(i,k) imes G(k,j)$

    $F_2$的计算式子是不是十分眼熟,这不就是矩阵乘法嘛!那么就有$F_2=G^2$了。

    让我们继续看下去:

    $F_3(i,j)=sum_{k=1}^n F_2(i,k) imes G(k,j)$

    $F_3=G^3$

    $F_4(i,j)=sum_{k=1}^n F_3(i,k) imes G(k,j)$

    $F_4=G^4$

    ……

    至此我们可以得出一个结论:对于一个邻接矩阵$X$,$X^y$中的第$a$行第$b$列所表示的意义就是从这个图中走$y$步后,从$a$点走到$b$点的方案数。

    得出这一个结论后,我们再来看一看这一道题。

    如果机器人不能自爆或者停留在原地的话,应该怎么做?

    显然,求出邻接矩阵的$t$次方即可。

    在这一个基础上,如何处理停留在原地不动这一行为呢?

    对于每个点,都让它向自己连一条边,构造一个自环即可。

    那么,如何处理自爆这一行为呢?

    构造一个原图之外的节点,将每个点都往它连一条边,只能进不能出,那么当这个机器人走到这个点时,就相当于自爆了。

    然后就是矩阵快速幂的基本操作了。

    #include<iostream>
    #include<cstdio>
        using namespace std;
        const int mod=2017;
    struct JvZhen {int f[35][35];} A,C,Res;
        int n=0,m=0;
    JvZhen XiangCheng(JvZhen X,JvZhen Y)
    {
        for(int i=0;i<=n;i++)
            for(int j=0;j<=n;j++) C.f[i][j]=0;
        for(int i=0;i<=n;i++)
            for(int j=0;j<=n;j++)
                for(int k=0;k<=n;k++)
                    C.f[i][j]=(C.f[i][j]+(X.f[i][k]*Y.f[k][j])%mod)%mod;
        return C;
    }
    void KuaiSuMi(int x)
    {
        while(x)
        {
            if(x&1) Res=XiangCheng(Res,A);
            A=XiangCheng(A,A);
            x>>=1; 
        }
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++) A.f[i][0]=A.f[i][i]=1;
        for(int i=1;i<=m;i++)
        {
            int u=0,v=0;
            scanf("%d%d",&u,&v);
            A.f[u][v]=A.f[v][u]=1;
        }
        int t=0;
        scanf("%d",&t);
        A.f[0][0]=1;
        Res=A,KuaiSuMi(t-1);
        int ans=0;
        for(int i=0;i<=n;i++) ans=(ans+Res.f[1][i])%mod;
        printf("%d",ans);
        return 0;
    }
    Luogu P3758
  • 相关阅读:
    处理器及其调度
    java面向对象
    操作系统概述
    mysql 基础操作
    java集合类详解
    java数组
    java方法
    Python—进程间通信
    Python—TCP的黏包问题以及UDP的分片问题
    Python—网络通信编程之tcp非阻塞通信(socketserver)
  • 原文地址:https://www.cnblogs.com/wozaixuexi/p/10221128.html
Copyright © 2011-2022 走看看