zoukankan      html  css  js  c++  java
  • 【洛谷P2151】[SDOI2009]HH去散步

    题目描述

    HH有个一成不变的习惯,喜欢饭后百步走。所谓百步走,就是散步,就是在一定的时间 内,走过一定的距离。 但是同时HH又是个喜欢变化的人,所以他不会立刻沿着刚刚走来的路走回。 又因为HH是个喜欢变化的人,所以他每天走过的路径都不完全一样,他想知道他究竟有多 少种散步的方法。

    现在给你学校的地图(假设每条路的长度都是一样的都是1),问长度为t,从给定地 点A走到给定地点B共有多少条符合条件的路径

    输入输出格式

    输入格式:

    第一行:五个整数N,M,t,A,B。其中N表示学校里的路口的个数,M表示学校里的 路的条数,t表示HH想要散步的距离,A表示散步的出发点,而B则表示散步的终点。

    接下来M行,每行一组Ai,Bi,表示从路口Ai到路口Bi有一条路。数据保证Ai != Bi,但 不保证任意两个路口之间至多只有一条路相连接。 路口编号从0到N − 1。 同一行内所有数据均由一个空格隔开,行首行尾没有多余空格。没有多余空行。 答案模45989。

    输出格式:

    一行,表示答案。

    输入输出样例

    输入样例#1:
    4 5 3 0 0
    0 1
    0 2
    0 3
    2 1
    3 2
    输出样例#1:
    4

    说明

    对于30%的数据,N ≤ 4,M ≤ 10,t ≤ 10。

    对于100%的数据,N ≤ 50,M ≤ 60,t ≤ 2^30,0 ≤ A,B

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int mod=45989;
    inline int read(){
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9') ch=getchar();
        while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
        return x*f;
    }
    int n,m,t,A,B,tot=1;
    int head[66];
    struct node{
        int from,to,next;
    }e[200];
    struct Mat {
        int m[125][125];
    }a,b;
    inline void insert(int from,int to){
        e[++tot].next=head[from];
        e[tot].from=from;
        e[tot].to=to;
        head[from]=tot;
    }
    inline Mat matmul(Mat a,Mat b){
        Mat res;
        for(register int i=1;i<=tot;++i)
            for(register int j=1;j<=tot;++j){
                res.m[i][j]=0;
                for(register int k=1;k<=tot;++k)
                    res.m[i][j]=(res.m[i][j]+a.m[i][k]*b.m[k][j])%mod;
            }
        return res;
    }
    inline Mat matpow(Mat a,int p){
        Mat res=a; --p;
        for(;p;p>>=1,a=matmul(a,a))
            if(p&1) res=matmul(res,a);
        return res;
    }
    int main(){
        n=read();m=read();t=read();A=read();B=read();
        register int u,v;
        for(register int i=1;i<=m;++i){
            u=read();v=read();
            insert(u,v);insert(v,u);
        }
        int cnt=0;
        for(int i=head[A];i;i=e[i].next) ++a.m[1][i];
        for(int i=2;i<=tot;++i)
            for(int j=2;j<=tot;++j)
                if(e[i].to==e[j].from)
                    if(i!=(j^1)) ++b.m[i][j];
        a=matmul(a,matpow(b,t-1));
        for(int i=head[B];i;i=e[i].next)
            cnt+=a.m[1][i^1];
        printf("%d
    ",cnt%mod);
        return 0;
    }
    欢迎转载,转载请注明出处!
  • 相关阅读:
    LeetCode 842. Split Array into Fibonacci Sequence
    LeetCode 1087. Brace Expansion
    LeetCode 1219. Path with Maximum Gold
    LeetCode 1079. Letter Tile Possibilities
    LeetCode 1049. Last Stone Weight II
    LeetCode 1046. Last Stone Weight
    LeetCode 1139. Largest 1-Bordered Square
    LeetCode 764. Largest Plus Sign
    LeetCode 1105. Filling Bookcase Shelves
    LeetCode 1027. Longest Arithmetic Sequence
  • 原文地址:https://www.cnblogs.com/huihao/p/7684332.html
Copyright © 2011-2022 走看看