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

Source

Day1

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

若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 }

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

时间: 2024-11-05 12:29:28

BZOJ 1875[SDOI2009]HH去散步的相关文章

bzoj 1875: [SDOI2009]HH去散步 -- 矩阵乘法

1875: [SDOI2009]HH去散步 Time Limit: 20 Sec  Memory Limit: 64 MB Description HH有个一成不变的习惯,喜欢饭后百步走.所谓百步走,就是散步,就是在一定的时间 内,走过一定的距离. 但 是同时HH又是个喜欢变化的人,所以他不会立刻沿着刚刚走来的路走回. 又因为HH是个喜欢变化的人,所以他每 天走过的路径都不完全一样,他想知道他究竟有多 少种散步的方法. 现在给你学校的地图(假设每条路的长度都 是一样的都是1),问长度为t,从给定

BZOJ 1875: [SDOI2009]HH去散步( dp + 矩阵快速幂 )

把双向边拆成2条单向边, 用边来转移...然后矩阵乘法+快速幂优化 --------------------------------------------------------------------------------------------- #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int MOD = 45989; const int

bzoj 1875 [SDOI2009]HH去散步(矩乘)

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

[DP 矩阵快速幂] BZOJ 1875 [SDOI2009]HH去散步

一个DP 用矩阵快速幂加速 然后这个DP状态比较巧妙 以边作状态 #include<cstdio> #include<cstdlib> #include<algorithm> #include<cstring> #define cl(x) memset(x,0,sizeof(x)) using namespace std; inline char nc() { static char buf[100000],*p1=buf,*p2=buf; if (p1==

1875: [SDOI2009]HH去散步

Time Limit: 20 Sec Memory Limit: 64 MB Submit: 2333 Solved: 1204 [Submit][Status][Discuss] Description HH有个一成不变的习惯,喜欢饭后百步走.所谓百步走,就是散步,就是在一定的时间 内,走过一定的距离. 但 是同时HH又是个喜欢变化的人,所以他不会立刻沿着刚刚走来的路走回. 又因为HH是个喜欢变化的人,所以他每 天走过的路径都不完全一样,他想知道他究竟有多 少种散步的方法. 现在给你学校的地图

BZOJ1875: [SDOI2009]HH去散步

1875: [SDOI2009]HH去散步 Time Limit: 20 Sec  Memory Limit: 64 MBSubmit: 620  Solved: 265[Submit][Status] Description HH有个一成不变的习惯,喜欢饭后百步走.所谓百步走,就是散步,就是在一定的时间 内,走过一定的距离. 但是同时HH又是个喜欢变化的人,所以他不会立刻沿着刚刚走来的路走回. 又因为HH是个喜欢变化的人,所以他每天走过的路径都不完全一样,他想知道他究竟有多 少种散步的方法.

BZOj-1875: [SDOI2009]HH去散步 (矩阵快速幂)

1875: [SDOI2009]HH去散步 Time Limit: 20 Sec  Memory Limit: 64 MBSubmit: 1999  Solved: 980[Submit][Status][Discuss] Description HH有个一成不变的习惯,喜欢饭后百步走.所谓百步走,就是散步,就是在一定的时间 内,走过一定的距离. 但 是同时HH又是个喜欢变化的人,所以他不会立刻沿着刚刚走来的路走回. 又因为HH是个喜欢变化的人,所以他每 天走过的路径都不完全一样,他想知道他究竟

[SDOI2009]HH去散步

[SDOI2009]HH去散步 题目描述 HH有个一成不变的习惯,喜欢饭后百步走.所谓百步走,就是散步,就是在一定的时间 内,走过一定的距离. 但是同时HH又是个喜欢变化的人,所以他不会立刻沿着刚刚走来的路走回. 又因为HH是个喜欢变化的人,所以他每天走过的路径都不完全一样,他想知道他究竟有多 少种散步的方法. 现在给你学校的地图(假设每条路的长度都是一样的都是1),问长度为t,从给定地 点A走到给定地点B共有多少条符合条件的路径 输入输出格式 输入格式: 第一行:五个整数N,M,t,A,B.其

【BZOJ1875】【矩阵乘法】[SDOI2009]HH去散步

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