zoukankan      html  css  js  c++  java
  • 【HDU 2157】 How Many Ways??

    【题目链接】

                点击打开链接

    【算法】

               设A[i][j]为走一条边,从i走到j的方案数

               C[i][j]为走两条边,从i走到j的方案数,显然有 : C = A * A = A^2

               C'[i][j]为走三条边,从i走到j的方案数,那么 : C' = C * A = (A * A) * A = A^3

               .......

              因此,要求走n条边的方案数,只需通过矩阵乘法快速幂,计算A^n就可以了

     【代码】

                注意,一个n阶矩阵的零次幂是n阶单位阵(对角线上的都是1,其余都是0)

    #include<bits/stdc++.h>
    using namespace std;
    #define MAXN 25
    const int MOD = 1000;
    
    int n,m,s,t,a,b,k;
    struct Matrix
    {
        int mat[MAXN][MAXN];
    } c,ans;
    
    inline void multipy(Matrix &a,Matrix b)
    {
        int i,j,k;
        Matrix ans;
        memset(ans.mat,0,sizeof(ans.mat));
        for (i = 0; i < n; i++)
        {
            for (j = 0; j < n; j++)
            {
                for (k = 0; k < n; k++)
                {
                    ans.mat[i][j] = (ans.mat[i][j] + a.mat[i][k] * b.mat[k][j]) % MOD;
                }
            }
        }
        a = ans;
    }
    
    inline Matrix power(Matrix a,int n,int s)
    {
        int i,j;
        Matrix ans,p = a;
        for (i = 0; i < s; i++)
        {
            for (j = 0; j < s; j++)
            {
                ans.mat[i][j] = (i == j);
            }
        }
        while (n > 0)
        {
            if (n & 1) multipy(ans,p);
            multipy(p,p);
            n >>= 1;
        }
        return ans;
    }
    
    int main()
    {
        
        while (scanf("%d%d",&n,&m) != EOF)
        {
            if (!n && !m) break;
            memset(c.mat,0,sizeof(c.mat));
            while (m--)
            {
                scanf("%d%d",&s,&t);
                c.mat[s][t] = 1;    
            }    
            scanf("%d",&t);
            while (t--)
            {
                scanf("%d%d%d",&a,&b,&k);
                ans = power(c,k,n);
                printf("%d
    ",ans.mat[a][b]);
            }
        }
        
        return 0;
    }


  • 相关阅读:
    二叉树前、中、后遍历
    程序员节宜冒泡
    HashMap源码分析
    Stack源码解析
    逆袭之旅DAY24.XIA.二重进阶、双色球
    逆袭之旅DAY24.XIA.数组练习
    LY.JAVA面向对象编程.内部类
    LY.JAVA面向对象编程.修饰符
    LY.JAVA面向对象编程.包的概述、导包
    XIA.人机猜拳
  • 原文地址:https://www.cnblogs.com/evenbao/p/9196313.html
Copyright © 2011-2022 走看看