[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
很容易往矩阵上面想
但是不能立刻返回,这看似无法用矩阵
其实可以点边互化,将点的连接转为边的连接,这样就可以排除非法情况
如果一条边终点于另一条边起点相同且不为一条边,那么这两条边连接
于是转为构建边的矩阵Mat
然后求出Matt-1
初始矩阵pre:以A为起点的边
答案:ans=pre*Matt-1,将∑ans[1][i]输出(i终点为B)
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 typedef long long ll; 7 int Mod=45989; 8 struct Node 9 { 10 int u,v; 11 }edge[121]; 12 struct Matrix 13 { 14 ll a[121][121]; 15 }ans,pre,Mat; 16 int tot,n,m,A,B,t; 17 ll zyys; 18 Matrix operator*(const Matrix &x,const Matrix &y) 19 {int i,j,k; 20 Matrix res; 21 memset(res.a,0,sizeof(res.a)); 22 for (i=0;i<=tot;i++) 23 { 24 for (j=0;j<=tot;j++) 25 { 26 for (k=0;k<=tot;k++) 27 { 28 res.a[i][j]+=x.a[i][k]*y.a[k][j]; 29 res.a[i][j]%=Mod; 30 } 31 } 32 } 33 return res; 34 } 35 Matrix qpow(int x) 36 {int i; 37 Matrix res; 38 memset(res.a,0,sizeof(res.a)); 39 for (i=0;i<=tot;i++) 40 res.a[i][i]=1; 41 while (x) 42 { 43 if (x&1) res=res*Mat; 44 Mat=Mat*Mat; 45 x/=2; 46 } 47 return res; 48 } 49 int main() 50 {int u,v,i,j; 51 cin>>n>>m>>t>>A>>B; 52 A++;B++; 53 tot=-1; 54 for (i=1;i<=m;i++) 55 { 56 scanf("%d%d",&u,&v); 57 u++;v++; 58 ++tot; 59 edge[tot].u=u;edge[tot].v=v; 60 ++tot; 61 edge[tot].v=u;edge[tot].u=v; 62 } 63 for (i=0;i<=tot;i++) 64 { 65 for (j=0;j<=tot;j++) 66 if (i!=j&&((i^1)!=j)&&edge[i].v==edge[j].u) 67 { 68 Mat.a[i][j]=1; 69 } 70 } 71 for (i=0;i<=tot;i++) 72 if (edge[i].u==A) 73 pre.a[1][i]=1; 74 ans=qpow(t-1); 75 ans=pre*ans; 76 for (i=0;i<=tot;i++) 77 if (edge[i].v==B) 78 { 79 zyys+=ans.a[1][i]; 80 zyys%=Mod; 81 } 82 cout<<zyys; 83 }