可惜没如果=_=
时光的河入海流

1875: [SDOI2009]HH去散步

Time Limit: 20 Sec  Memory Limit: 64 MB
Submit: 1999  Solved: 980
[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

laj一开始把题目看错了= = 不能走回头路哇……laj就说这题怎么可能这么傻逼呢……
然后就是很神的做法咯……把边存到矩阵里收尾相接的两条边在矩阵里连边,然后求t-1次幂,在开另一个矩阵,剩下的开代码qwq
laj又忘记膜辣……wa了一发 _(:зゝ∠)_
 1 #include "bits/stdc++.h"
 2 using namespace std;
 3 typedef long long LL;
 4 const int MAX=205,mod=45989;
 5 int n,m,t,st,ed;
 6 struct Mat{
 7     int x,y;
 8     int mat[MAX][MAX];
 9     Mat(){x=y=0;memset(mat,0,sizeof(mat));}
10     friend Mat operator * (Mat cc,Mat tt) {
11         Mat an;int i,j,k;
12         an.x=cc.x,an.y=tt.y;
13         for (i=1;i<=cc.x;i++)
14             for (k=1;k<=cc.y;k++)
15                 if (cc.mat[i][k])
16                     for (j=1;j<=an.y;j++)
17                         an.mat[i][j]=(an.mat[i][j]+cc.mat[i][k]*tt.mat[k][j])%mod;
18         return an;
19     }
20     friend Mat operator ^(Mat cc,int tt) {
21         Mat an;int i,j;
22         an.x=cc.x,an.y=cc.y;
23         for (i=1;i<=cc.x;i++) an.mat[i][i]=1;
24         while (tt){
25             if (tt&1) an=an*cc;
26             cc=cc*cc,tt>>=1;
27         }
28         return an;
29     }
30     void out(){
31         int i,j;
32         for (i=1;i<=x;i++){
33             for (j=1;j<=y;j++)
34                 printf("%d ",mat[i][j]);
35             printf("\n");
36         }
37         printf("\n");
38     }
39 }a,b;
40 struct Edge{int x,y;}edge[1005];
41 int tot,head[MAX],adj[1005],next[1005];
42 void addedge(int u,int v){tot++;adj[tot]=v,next[tot]=head[u],head[u]=tot,edge[tot].x=u,edge[tot].y=v;}
43 inline int read(){
44     int an=0,x=1;char c=getchar();
45     while (c<'0' || c>'9') {if (c=='-') x=-1;c=getchar();}
46     while (c>='0' && c<='9') {an=(an<<3)+(an<<1)+c-'0';c=getchar();}
47     return an*x;
48 }
49 int main(){
50     freopen ("walk.in","r",stdin);freopen ("walk.out","w",stdout);
51     int i,j,x,y;tot=1;
52     n=read(),m=read(),t=read(),st=read(),ed=read();st++,ed++;
53     for (i=1;i<=m;i++){
54         x=read(),y=read();x++,y++;
55         addedge(x,y),addedge(y,x);
56     }
57     a.x=a.y=b.x=b.y=tot;
58     for (i=head[st];i;i=next[i]) a.mat[1][i]++;
59     for (i=2;i<=tot;i++)
60         for (j=2;j<=tot;j++)
61             if (edge[i].y==edge[j].x && i!=(j^1))
62                 b.mat[i][j]++;
63     a=a*(b^(t-1));
64     int ans=0;
65     for (i=head[ed];i;i=next[i])
66         ans+=a.mat[1][i^1];
67     printf("%d",ans%mod);
68     return 0;
69 }

 

posted on 2017-11-09 00:29  珍珠鸟  阅读(156)  评论(0编辑  收藏  举报