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。
Output
一行,表示答案。
Sample Input
4 5 3 0 0
0 1
0 2
0 3
2 1
3 2
Sample Output
4
HINT
对于30%的数据,N ≤ 4,M ≤ 10,t ≤ 10。
对于100%的数据,N ≤ 20,M ≤ 60,t ≤ 230,0 ≤ A,B
Source
Day1
矩乘DP.
根据边的关系建出矩阵然后做快速幂.
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define MAXN 250
#define P 45989
using namespace std;
int n,m,t,A,B;
int top=1,size;
int ans;
struct edge
{
int from,to,num;
edge *next;
}e[MAXN<<1],*prev[MAXN];
void insert(int u,int v)
{
e[++top].to=v;e[top].next=prev[u];prev[u]=&e[top];e[top].num=top;e[top].from=u;
}
struct matrix
{
int a[MAXN][MAXN];
matrix()
{
memset(a,0,sizeof(a));
}
friend matrix operator *(matrix A,matrix B)
{
matrix ret;
for (int i=1;i<=size;i++)
for (int j=1;j<=size;j++)
for (int k=1;k<=size;k++)
ret.a[i][j]=(ret.a[i][j]+A.a[i][k]*B.a[k][j])%P;
return ret;
}
friend matrix operator ^(matrix x,int k)
{
matrix ret;
for (int i=1;i<=size;i++) ret.a[i][i]=1;
for (int i=k;i;i>>=1,x=x*x)
if (i&1) ret=ret*x;
return ret;
}
}st,tmp;
int main()
{
scanf("%d%d%d%d%d",&n,&m,&t,&A,&B);
for (int i=1;i<=m;i++)
{
int u,v;
scanf("%d%d",&u,&v);
insert(u,v);insert(v,u);
}
size=top;
for (edge *i=prev[A];i;i=i->next) st.a[1][i->num]++;
for (int i=2;i<=top;i++)
for (int j=2;j<=top;j++)
if (e[i].to==e[j].from&&i!=(j^1)) tmp.a[i][j]++;
st=st*(tmp^(t-1));
for (edge *i=prev[B];i;i=i->next) ans+=st.a[1][i->num^1];
ans%=P;
printf("%d\n",ans);
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-10-12 07:25:42