\(Description:\)

给出一张图,求\(A->B\),经过t的时间之后的方案数,答案对45989取模。

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。

但不能\(a->b\),马上,\(b->a\)

\(Sample\) \(Input\):

4 5 3 0 0
0 1
0 2
0 3
2 1
3 2

\(Sample\) \(Output:\)

4

\(Solution:\)

很明显这题是矩乘,但不知道怎么管那个限制条件。

这又是套路题。。。

考虑边是不会走反的,那么把边变成矩阵的点,这样就可以保障不会走反。

那么只有在两条边中一条边的终点为另一条起点时才可以连

然后一开始要强制走到A,做t-1次幂。

再把强制走的矩阵乘上去,最后统计终点为B的边的答案。

#pragma GCC optimize("inline")
#include<cstdio>
#include<iostream>
#include<cstring>
#define int long long 
#define one first
#define two second
using namespace std;
int n,m,t,A,B,En,cnt,ans;
const int N=120*2,p=45989;
pair<int,int> E[N+5];
struct matrix {
    int n,m;
    int a[N+5][N+5];
    inline void clear() { n=m=0;memset(a,0,sizeof(a));}
    inline void set(int nx) { n=m=nx;for(int i=1;i<=nx;++i) a[i][i]=1;}
    inline void write() const{
        for(int i=1;i<=n;++i){
            for(int j=1;j<=m;++j) cout<<a[i][j]<<" ";
            cout<<endl;
        }
        putchar('\n');
    }
    inline matrix operator *  (const matrix &nt) const {
        matrix tmp;tmp.clear();
        tmp.n=n;tmp.m=nt.m;
        for(int i=1;i<=n;++i) for(int j=1;j<=nt.m;++j) for(int k=1;k<=m;++k)
            tmp.a[i][j]=(tmp.a[i][j]+a[i][k]*nt.a[k][j]%p)%p;
        return tmp;
    }
    inline matrix operator *= (const matrix &nt) { return (*this)=(*this)*nt;}
}a,b;
inline matrix power(matrix x,int b){
    matrix ret;ret.clear();
    ret.set(x.n);
    while(b>0){
        if(b&1) ret=ret*x;
        x=x*x;
        b>>=1;
    }
    return ret;
}
signed main(){
    if(fopen("desire.in","r")){
        freopen("desire.in","r",stdin);
        freopen("desire.out","w",stdout);
    }
    ios::sync_with_stdio(0);
    cin>>n>>m>>t>>A>>B;
    for(int i=1;i<=m;++i){
        int u=0,v=0;
        cin>>u>>v;
        E[++En]=make_pair(u,v);
        E[++En]=make_pair(v,u);
    }
    a.n=1;a.m=En;
    b.n=En;b.m=En;
    for(int i=1;i<=En;++i) for(int j=1;j<=En;++j){
        if(((i&1) && i+1==j) || (!(i&1) && i-1==j) || i==j) continue;
        if(E[i].two==E[j].one) b.a[i][j]=1;
    }
        
    for(int i=1;i<=En;++i) if(E[i].one==A) a.a[1][i]=1;
    a=a*power(b,t-1);
    for(int i=1;i<=En;++i) if(E[i].two==B) ans=(ans+a.a[1][i])%p;
    cout<<ans<<endl;
    return 0;
}


扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄