zoukankan      html  css  js  c++  java
  • hdu 2254 奥运

    点击打开hdu 2254

    思路: 矩阵乘法

    分析:

    1 题目给定一个有向图,要求t1-t2天内v1-v2的路径的个数

    2 根据离散数学里面的可达矩阵的性质,我们知道一个有向图的邻接矩阵的前n次幂的和即为可达矩阵,那么要求[t1-t2]之内的路径的条数,假设邻接矩阵为A,那么要求的就是A^(t1-1)+A^(t1)+...+A^t2,为什么是从t1-1开始呢,因为邻接矩阵本身代表走一步的结果

    3 还有点的范围很大,边数很少,所以我们应该要进行离散化

    4 但是数据量很大,对于具体的一组我们应该要事先求出具体的每一个矩阵,然后直接使用即可


    代码:

    /************************************************
     * By: chenguolin                               * 
     * Date: 2013-08-25                             *
     * Address: http://blog.csdn.net/chenguolinblog *
     ***********************************************/
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    
    typedef __int64 int64;
    const int MOD = 2008;
    const int MAXN = 10000;
    const int N = 30;
    
    int n , pos;
    int64 num[2*MAXN];
    struct Edge{
        int64 x;
        int64 y;
    };
    Edge e[MAXN];
    
    struct Matrix{
        int mat[N][N];
        Matrix operator*(const Matrix& m)const{
            Matrix tmp;
            for(int i = 0 ; i < pos ; i++){
                for(int j = 0 ; j < pos ; j++){
                    tmp.mat[i][j] = 0;
                    for(int k = 0 ; k < pos ; k++){
                        tmp.mat[i][j] += mat[i][k]*m.mat[k][j]%MOD;
                        tmp.mat[i][j] %= MOD;
                    }
                }
            }
            return tmp;
        }
    };
    Matrix ma[MAXN];
    
    int search(int64 x){
        int left = 0;
        int right = pos-1;
        while(left <= right){
            int mid = (left+right)>>1;
            if(num[mid] == x)
                return mid;
            else if(num[mid] < x)
                left = mid+1;
            else
                right = mid-1;
        }
        return -1;
    }
    
    void init(Matrix &m){
        memset(m.mat , 0 , sizeof(m.mat));
        sort(num , num+pos);
        pos = unique(num , num+pos)-num;
        for(int i = 0 ; i < n ; i++){
            int x = search(e[i].x);
            int y = search(e[i].y);
            m.mat[x][y]++;
        }
    }
    
    void Pow(Matrix m){
        ma[0] = m;
        for(int i = 1 ; i < MAXN ; i++)
            ma[i] = ma[i-1]*m; 
    }
    
    void solve(){
        Matrix m;
        init(m);
        Pow(m);
    
        int64 v1 , v2;
        int k , t1 , t2;
        scanf("%d" , &k);
        while(k--){
            scanf("%I64d%I64d%d%d" , &v1 , &v2 , &t1 , &t2); 
            if(t1 > t2 || t2 == 0){
                puts("0");
                continue;
            }
            int x = search(v1); 
            int y = search(v2); 
            if(x == -1 || y == -1){
                puts("0");
                continue;
            }
            int sum = 0;
            for(int i = t1-1 ; i < t2 ; i++){
                sum += ma[i].mat[x][y]%MOD;
                sum %= MOD;
            }
            printf("%d
    " , sum);
        }
    }
    
    int main(){
        while(scanf("%d" , &n) != EOF){
            pos = 0; 
            for(int i = 0 ; i < n ; i++){
                scanf("%I64d%I64d" , &e[i].x , &e[i].y);
                num[pos++] = e[i].x;
                num[pos++] = e[i].y;
            }
            solve();
        }
        return 0;
    }
    
    


  • 相关阅读:
    POJ2965(The Pilots Brothers' refrigerator)
    POJ1753(Flip Game)
    POJ3253(Fence Repair)
    山东理工大学的训练计划
    loutsScript 常用代码
    《大道至简》读后感
    2019暑第三周
    2019暑第二周
    2019暑第一周
    关于13组作品《TD tree》的使用感想
  • 原文地址:https://www.cnblogs.com/keanuyaoo/p/3281236.html
Copyright © 2011-2022 走看看