zoukankan      html  css  js  c++  java
  • bzoj1875 边点互换+矩乘

    https://www.lydsy.com/JudgeOnline/problem.php?id=1875

    题意 HH有个一成不变的习惯,喜欢饭后百步走。所谓百步走,就是散步,就是在一定的时间 内,走过一定的距离。 但

    是同时HH又是个喜欢变化的人,所以他不会立刻沿着刚刚走来的路走回。 又因为HH是个喜欢变化的人,所以他每
    天走过的路径都不完全一样,他想知道他究竟有多 少种散步的方法。 现在给你学校的地图(假设每条路的长度都
    是一样的都是1),问长度为t,从给定地 点A走到给定地点B共有多少条符合条件的路径
     
    开始没有看到不能走回头路的条件,以为是道人尽皆知傻逼矩阵快速幂,WA了好几发后才发现这个奇形怪状的条件。
    既然不能走回头路,我们就不能用点构造矩阵了,考虑直接用边来构造矩阵,表示边与边之间到达的关系。
    dp[i][j]表示边i通过k次操作到达边j的数目。
    我们建立两个虚点,一个x指向所有起点为S的边,一个y被所有终点为T的边指向,最终x需要经过K + 1条边到达y的数目即为答案
    构造矩阵即可。
    #include <map>
    #include <set>
    #include <ctime>
    #include <cmath>
    #include <queue>
    #include <stack>
    #include <vector>
    #include <string>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <sstream>
    #include <iostream>
    #include <algorithm>
    #include <functional>
    using namespace std;
    #define For(i, x, y) for(int i=x;i<=y;i++)  
    #define _For(i, x, y) for(int i=x;i>=y;i--)
    #define Mem(f, x) memset(f,x,sizeof(f))  
    #define Sca(x) scanf("%d", &x)
    #define Sca2(x,y) scanf("%d%d",&x,&y)
    #define Scl(x) scanf("%lld",&x);  
    #define Pri(x) printf("%d
    ", x)
    #define Prl(x) printf("%lld
    ",x);  
    #define CLR(u) for(int i=0;i<=N;i++)u[i].clear();
    #define LL long long
    #define ULL unsigned long long  
    #define mp make_pair
    #define PII pair<int,int>
    #define PIL pair<int,long long>
    #define PLL pair<long long,long long>
    #define pb push_back
    #define fi first
    #define se second 
    typedef vector<int> VI;
    const double eps = 1e-9;
    const int maxn = 125;
    const int INF = 0x3f3f3f3f;
    const int mod = 45989; 
    int N,M,tmp,K,tot; 
    int S,T;
    struct Mat{
        LL a[maxn][maxn];
        void init(){
            Mem(a,0);
        }
    }base;
    struct Edge{
        int u,v;
        Edge(int u = 0,int v = 0):u(u),v(v) {}
    }edge[maxn];
    Mat operator * (Mat a,Mat b){
        Mat ans; ans.init();
        for(int i = 0 ; i <= tot ; i ++){
            for(int j = 0 ; j <= tot; j ++){
                for(int k = 0; k <= tot; k ++){
                    ans.a[i][j] = (ans.a[i][j] + a.a[i][k] * b.a[k][j]) % mod;
                }
            }
        }
        return ans;
    }
    Mat operator ^ (Mat a,int b){
        Mat x,y = a;
        x.init();
        For(i,0,tot) x.a[i][i] = 1;
        while(b){
            if(b & 1) x = x * y;
            b >>= 1;
            y = y * y;
        }
        return x;
    }
    void solve(){
        base = base ^ (K + 1);
        printf("%lld",base.a[0][1]);
    }
    int main()
    {
        scanf("%d%d%d%d%d",&N,&M,&K,&S,&T);
        base.init(); tot = 2;
        For(i,1,M){
            int u,v; Sca2(u,v);
            edge[tot++] = Edge(u,v);
            edge[tot++] = Edge(v,u); 
        }
        tot--;
        For(i,2,tot){
            if(edge[i].u == S) base.a[0][i] = 1;
            if(edge[i].v == T) base.a[i][1] = 1;
            For(j,2,tot){
                if(edge[i].v == edge[j].u && (i ^ j ) != 1) base.a[i][j] = 1;
            }
        }
        solve();
        #ifdef VSCode
        system("pause");
        #endif
        return 0;
    }
  • 相关阅读:
    Hadoop学习笔记
    Hadoop学习笔记 -伪分布式
    SSH 连接报错总结
    Hadoop学习笔记
    Trie 前缀树/字典树
    解数独(Leetcode-37 / HDU-1426)/回溯/状态压缩
    MyBatis 多表关联查询
    python_37期自动化【lemon】
    api课堂笔记_day14
    api课堂笔记_day12&day13
  • 原文地址:https://www.cnblogs.com/Hugh-Locke/p/9696849.html
Copyright © 2011-2022 走看看