您的位置:首页 > 其它

【SDOI2009】【BZOJ1875】HH去散步

2015-08-28 10:29 225 查看
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.

根据边的关系建出矩阵然后做快速幂.

[code]#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);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: