zoukankan      html  css  js  c++  java
  • BZOJ 1875[SDOI2009]HH去散步

    题面:

    1875: [SDOI2009]HH去散步

    Time Limit: 20 Sec  Memory Limit: 64 MB
    Submit: 1750  Solved: 851
    [Submit][Status][Discuss]

    Description

    HH有个一成不变的习惯,喜欢饭后百步走。所谓百步走,就是散步,就是在一定的时间 内,走过一定的距离。 但
    是同时HH又是个喜欢变化的人,所以他不会立刻沿着刚刚走来的路走回。 又因为HH是个喜欢变化的人,所以他每
    天走过的路径都不完全一样,他想知道他究竟有多 少种散步的方法。 现在给你学校的地图(假设每条路的长度都
    是一样的都是1),问长度为t,从给定地 点A走到给定地点B共有多少条符合条件的路径

    Input

    第一行:五个整数N,M,t,A,B。
    N表示学校里的路口的个数
    M表示学校里的 路的条数
    t表示HH想要散步的距离
    A表示散步的出发点
    B则表示散步的终点。
    接下来M行
    每行一组Ai,Bi,表示从路口Ai到路口Bi有一条路。
    数据保证Ai != Bi,但不保证任意两个路口之间至多只有一条路相连接。 
    路口编号从0到N -1。 
    同一行内所有数据均由一个空格隔开,行首行尾没有多余空格。没有多余空行。 
    答案模45989。
    N ≤ 20,M ≤ 60,t ≤ 2^30,0 ≤ A,B

    Output

    一行,表示答案。

    Sample Input

    4 5 3 0 0
    0 1
    0 2
    0 3
    2 1
    3 2

    Sample Output

    4

    HINT

    这不是裸的矩阵乘(要是就好了),要建立边的矩阵。

    若v[i]==u[j],则g[i][j]=1(不能反过来,因为存的是单向边)。

    1*cnt的矩阵f[1][i]=[u[i]==start]。

    ans=f*g^(step-1)。答案为ans[1][i](v[i]==end)的和。

     1 #include<iostream>
     2 #include<stdio.h>
     3 #include<string.h>
     4 using namespace std;
     5 #define mod 45989
     6 int u[151],v[151];
     7 int n,m,cnt,s,t,e;
     8 int sum;
     9 int belong[151];
    10 struct martix
    11 {
    12     int a[151][151];
    13     martix()
    14     {
    15         memset(a,0,sizeof(a));
    16     }
    17 };
    18 martix multiplay(martix x,martix y)
    19 {
    20     martix z;
    21     for(int i=1;i<=cnt;i++)  
    22         for(int j=1;j<=cnt;j++)
    23             for(int k=1;k<=cnt;k++)
    24                 z.a[i][j]=(z.a[i][j]+x.a[i][k]*y.a[k][j])%mod;
    25     return z;
    26 }
    27 martix qpow(martix x,int y)
    28 {
    29     martix a,z;
    30     z=x;
    31     for(int i=0;i<=150;i++)
    32         a.a[i][i]=1;
    33     while(y)
    34     {
    35         if(y&1)
    36         {
    37             a=multiplay(a,z);
    38             --y;
    39         }
    40         z=multiplay(z,z);
    41         y>>=1;
    42     }
    43     return a;
    44 }
    45 int main()
    46 {
    47     int x,y;
    48     scanf("%d%d%d%d%d",&n,&m,&t,&s,&e);
    49     martix ans;
    50     martix bns;
    51     for(int i=1;i<=m;i++)
    52     {
    53         scanf("%d%d",&x,&y);
    54         u[++cnt]=x;
    55         v[cnt]=y;
    56         belong[cnt]=i;
    57         u[++cnt]=y;
    58         v[cnt]=x;
    59         belong[cnt]=i;
    60     }
    61     for(int i=1;i<=cnt;i++)
    62         for(int j=1;j<=cnt;j++)
    63             if(v[i]==u[j]&&belong[i]!=belong[j])
    64                 ans.a[i][j]=1;
    65     for(int i=1;i<=cnt;i++)
    66         if(u[i]==s)
    67             bns.a[1][i]=1;
    68     ans=qpow(ans,t-1);
    69     ans=multiplay(bns,ans);
    70     for(int i=1;i<=cnt;i++)
    71         if(v[i]==e)
    72             sum=(sum+ans.a[1][i])%mod;
    73     printf("%d",sum%mod);
    74 }
    BZOJ 1875

    (PS:矩阵乘法不满足交换律)

  • 相关阅读:
    js对象Array —— 使用.操作符和用['xxx']访问对象的区别
    JavaScript为字符串提供的一些常用方法
    ES6新增属性——,模板字符串`` 中可使用${ }代替‘+’字符串拼接
    【vue】使用vue+element搭建项目,Tree树形控件使用
    vue循环遍历List,Map,Array
    解决分页查询只能查到本页信息的问题
    vue之 js字符串驼峰和下划线互相转换
    PHP中的对象遍历技巧
    php类的复制(克隆)
    php类的自动加载
  • 原文地址:https://www.cnblogs.com/radioteletscope/p/7162078.html
Copyright © 2011-2022 走看看