zoukankan      html  css  js  c++  java
  • [SCOI2009]迷路(矩阵快速幂) 题解

    Description

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

    Input

    第一行包含两个整数,N T。 接下来有 N 行,每行一个长度为 N 的字符串。 第i行第j列为'0'表示从节点i到节点j没有边。 为'1'到'9'表示从节点i到节点j需要耗费的时间。

    Output

    包含一个整数,可能的路径数,这个数可能很大,只需输出这个数除以2009的余数。

    Sample Input

    【输入样例一】
    2 2
    11
    00

    【输入样例二】
    5 30
    12045
    07105
    47805
    12024
    12345


    Sample Output

    【输出样例一】
    1

    【样例解释一】
    0->0->1

    【输出样例二】
    852

    HINT

    30%的数据,满足 2 <= N <= 5 ; 1 <= T <= 30 。 100%的数据,满足 2 <= N <= 10 ; 1 <= T <= 1000000000 。

    结论:对于边权都相同的邻接矩阵$G$,$G^T$表示两点间长度为$T$的路径的方案数。

    考虑矩阵乘法在这类题中的实际意义:

    $a[i][j]=sum b[i][k]*b[k][j]$     可以把k看作枚举的中继,就得到了更进一步的方案数

    $(i->j)的方案数 = (i->k)的方案数 * (k->j)的方案数  (起点终点固定)$

    自乘$n-1$次即可得到两点间长度为n的方案数。

    虽然这道题带权,但可以注意到边权种类很少,完全可以在一条路上强行加点起到统一边权的效果。

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    using namespace std;
    const int N=105,mod=2009;
    struct matrix
    {
        int a[N][N];
        matrix()
        {
            memset(a,0,sizeof(a));
        }
    }g;
    int n,T;
    matrix operator * (matrix x,matrix y)
    {
        matrix res;
        for(int i=0;i<n*9;i++)
            for(int j=0;j<n*9;j++)
                for(int k=0;k<n*9;k++)
                    (res.a[i][j]+=x.a[i][k]*y.a[k][j])%=mod;
        return res;
    }
    matrix qpow(matrix a,int b)
    {
        matrix res=a;
        while(b)
        {
            if(b&1)res=res*a;
            a=a*a;;
            b>>=1;
        }
        return res;
    }
    int main()
    {
        scanf("%d%d",&n,&T);
        char s[N];
        for(int i=0;i<n;i++)
        {
            scanf("%s",s);
            for(int j=0;j<n;j++)
            {
                if(s[j]=='0')continue;
                int x=s[j]-'0';
                x--;
                g.a[i*9+x][j*9]=1;
            }
            for(int j=0;j<8;j++)
                g.a[i*9+j][i*9+j+1]=1;
        }
        matrix res=qpow(g,T-1);
        cout<<res.a[0][9*(n-1)]<<endl;
        return 0;
    }
  • 相关阅读:
    hbase 得到一行的数据详情
    文件上传
    es 启动用户
    es 分片丢失
    es 调整查询窗口
    hbase 字段值开头查询
    maven 项目linux运行可执行jar
    hbase count 扫表查询
    hbase 查询空串空字段
    sql常用手法(二)
  • 原文地址:https://www.cnblogs.com/Rorschach-XR/p/11203730.html
Copyright © 2011-2022 走看看