• B1297 [SCOI2009]迷路 矩阵


    这个题我觉得很有必要写一篇博客。首先,我们需要知道,假如一个邻接矩阵只有0/1构成,那么它自己的n次方就是走n步之后的方案数。但这个题还有2~9咋办呢。我们观察发现,这个题只有10个点,而且边权<=9我们可以想到拆点这个小操作。把每个点拆成9个点,点内连1的边,点外分别连到相应的权值就行了。

    题干:

    windy在有向图中迷路了。 该有向图有 N 个节点,windy从节点 0 出发,他必须恰好在 T 时刻到达节点 N-1。 现在给出该有向图,你能告诉windy总共有多少种不同的路径吗? 注意:windy不能在某个节点逗留,且通过某有向边的时间严格为给定的时间。

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<ctime>
    #include<queue>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    #define duke(i,a,n) for(register int i = a;i <= n;i++)
    #define lv(i,a,n) for(register int i = a;i >= n;i--)
    #define clean(a) memset(a,0,sizeof(a))
    const int INF = 1 << 30;
    const int mod = 2009;
    typedef long long ll;
    typedef double db;
    template <class T>
    void read(T &x)
    {
        char c;
        bool op = 0;
        while(c = getchar(), c < '0' || c > '9')
            if(c == '-') op = 1;
        x = c - '0';
        while(c = getchar(), c >= '0' && c <= '9')
            x = x * 10 + c - '0';
        if(op) x = -x;
    }
    template <class T>
    void write(T x)
    {
        if(x < 0) putchar('-'), x = -x;
        if(x >= 10) write(x / 10);
        putchar('0' + x % 10);
    }
    int m,T;
    struct Mat
    {
        int a[105][105],n;
        Mat()
        {
            n = m * 9;
            clean(a);
        }
        void I()
        {
    //        cout<<n<<endl;
            duke(i,1,n)
            {
                a[i][i] = 1;
            }
        }
        inline Mat operator * (const Mat &oth)
        {
            Mat res;
    //        cout<<n<<endl;
            duke(i,1,n)
            {
                duke(j,1,n)
                {
                    int sum = 0;
                    duke(k,1,n)
                    {
                        sum = (sum + a[i][k] * oth.a[k][j]) % mod;
                    }
                    res.a[i][j] = sum;
                }
            }
            return res;
        }
    }A,B;
    Mat qpow(Mat a,int k)
    {
        Mat c;
        c.I();
    //    cout<<k<<endl;
        while(k)
        {
            if(k % 2 == 1)
            {
                c = c * a;
            }
            a = a * a;
            k >>= 1;
    //        cout<<k<<endl;
        }
        return c;
    }
    char s[105];
    int main()
    {
        read(m);read(T);
        A.n = m * 9;
        duke(i,1,m)
        {
            duke(j,1,8)
            A.a[9 * (i - 1) + j][9 * (i - 1) + j + 1] = 1;
        }
        duke(i,1,m)
        {
            scanf("%s",s);
            duke(j,1,m)
            {
                if(s[j - 1] > '0')
                A.a[9 * (i - 1) + s[j - 1] - '0'][9 * (j - 1) + 1] = 1;
            }
        }
    //    cout<<"??"<<endl;
        B = qpow(A,T);
        printf("%d
    ",B.a[1][m * 9 - 8]);
        return 0;
    }
    /*
    2 2
    11
    00
    */
  • 相关阅读:
    神经网络层数问题
    matlab入门笔记(六):编程基础之M文件
    工字电感,色环电感,功率电感选型区别
    x电容和Y电容
    nohup.out文件过大解决方法 定时任务清空
    WebRTC的视频解码原理简析
    activemq 安装 部署
    WebRTC信令控制简介与STUN, TURN服务器搭建
    如何搭建WebRTC信令服务器
    ZooKeeper安装和配置
  • 原文地址:https://www.cnblogs.com/DukeLv/p/10091733.html
Copyright © 2020-2023  润新知