1875: [Sdoi2009]hh go for a walk
Time limit:20 Sec Memory limit:64 MB
submit:932 solved:424
[Submit] [Status] [Discuss]
Description
HH has a constant habit, like hundred steps after a meal. The so-called hundred step Walk, is a walk, is in a certain time, through a certain distance. But at the same time HH is a person who likes to change, so he will not immediately follow the road just walked back. And because HH is a person who likes to change, so he walks the path every day is not exactly the same, he wants to know how many ways he has to walk. Now give your school map (assuming that each road is the same length is 1), ask the length of T, from a given location A to a given location B total number of eligible paths
Input
First line: five integer n,m,t,a,b. where n indicates the number of intersections in the school, m indicates the number of roads in the school, T indicates the distance that HH wants to walk, a is the starting point for a walk, and B represents the end of the walk. The next m line, a set of Ai,bi per row, represents a road from the intersection AI to the intersection Bi. The data guarantees AI = Bi, but there is no guarantee that there is at most one route connected between any two intersections. Intersection number from 0 to n? 1. All data in the same row is separated by a space, and there is no extra space at the end of the line. There are no extra empty lines. Answer modulus 45989.
Output
A line that represents the answer.
Sample Input
4 5 3) 0 0
0 1
0 2
0 3
2 1
3 2
Sample Output
4
HINT
For 30% of data, n≤4,m≤10,t≤10.
For 100% of data, n≤20,m≤60,t≤230,0≤a,b
Source
Day1
Idea: For this problem we can save f[k][i][j] means to walk the K-step, through the side I reached the J
So obviously for this transfer, we can use matrix multiplication to optimize it.
Because there are heavy edges and can not be connected to the same side, so we have to split the non-edge into two of the side can solve the problem.
Build a matrix of 1* (2*m) and a matrix of (2 * m) * (2 * m) is available.
Finally, the edge from the starting point and into the end of the side of σ a bit.
#include <iostream>#include <cstdio>#include <cstring>using namespace Std;#define D 45989intNm, t,a,b,e1[ -][ -],e2[ -][ -],a[ Max][ Max],ans[ Max][ Max],c[ Max][ Max];bool f=true,pd[ Max][ Max];struct s{intSt,en;} aa[ Max];intMain () {intI,j,x,yK scanf"%d %d%d%d%d",&n,&m, &t,&a,&b); a+=1; b+=1; memset (PD,1, sizeof (PD)); for(i=1; i<=m; ++i) {scanf ("%d%d",&x,&y);x+=1;y+=1; e1[x][++e1[x][0]]=e2[y][++e2[y][0]]=2*i-1; e2[x][++e2[x][0]]=e1[y][++e1[y][0]]=2*i; pd[2*i-1][2*i]=pd[2*i][2*i-1]=false; aa[2*i-1].st=aa[2*i].en=x; aa[2*i-1].en=aa[2*i].st=y; } for(i=1; i<=2*m; ++i) for(j=1; j<=2*m; ++j)if(pd[i][j]&& (aa[i].en==aa[j].st)) a[i][j]+=1;y=t-1; while(y){if(y&1){if(f) { for(i=1; i<=2*m; ++i) for(j=1; j<=2*m; ++j) Ans[i][j]=a[i][j]; F=false; }Else{ for(i=1; i<=2*m; ++i) for(j=1; j<=2*m; ++j) {c[i][j]=0; for(k=1; k<=2*m; ++k) c[i][j]= (c[i][j]+ (a[i][k)*ansK [j])%d)%d; } for(i=1; i<=2*m; ++i) for(j=1; j<=2*m; ++j) Ans[i][j]=c[i][j]; } }y>>=1; for(i=1; i<=2*m; ++i) for(j=1; j<=2*m; ++j) {c[i][j]=0; for(k=1; k<=2*m; ++k) c[i][j]= (c[i][j]+ (a[i][k)*aK [j])%d)%d; } for(i=1; i<=2*m; ++i) for(j=1; j<=2*m; ++j) A[i][j]=c[i][j]; }intsum=0; for(i=1; i<=e1[a][0];++i) for(j=1; j<=e2[b][0];++J) sum= (Sum+ans[e1[a][i]][e2[b][j])%d;printf("%d\ n", sum);}
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
"bzoj1875" "SDOI2009" "HH Go for a walk"