BZOJ 1875 [SDOI2009]HH去散步

来源:互联网 发布:js获取浏览器宽高 编辑:程序博客网 时间:2024/05/24 06:00

大概是矩阵快速幂的一道裸题。。。

然后做着做着发现不对。。。好像条件还有限制,两次边不能重。然后苦思冥想好一阵决定抄题解。发现是把点的转移改为了边的转移,思路还是一样的。其实这道题莫名其妙给出m的范围就已经很可疑了,下次应该注意…

#include<iostream>#include<cstring>#include<cstdlib>#include<cstdio>#include<vector>#include<algorithm>using namespace std;const int mod=45989;struct Matrix {    int m[122][122];}A,B;int n,m,t,S,T,ans,cnt=-1;vector<int>begin[22],end[22];Matrix mul(Matrix x,Matrix y){    Matrix tmp;    memset(tmp.m,0,sizeof tmp.m);    for(int i=0;i<=cnt;i++)        for(int j=0;j<=cnt;j++)            for(int k=0;k<=cnt;k++)                tmp.m[i][j]=(tmp.m[i][j]+x.m[i][k]*y.m[k][j])%mod;    return tmp;}Matrix pow(Matrix x,int y){    Matrix tmp=x;    y--;    while(y)    {        if(y&1)tmp=mul(tmp,x);        x=mul(x,x);        y>>=1;    }    return tmp;}int main(){    scanf("%d%d%d%d%d",&n,&m,&t,&S,&T);    for(int i=1,x,y;i<=m;i++)    {        scanf("%d%d",&x,&y);        begin[x].push_back(cnt+1);        end[y].push_back(cnt+1);        begin[y].push_back(cnt+2);        end[x].push_back(cnt+2);        cnt+=2;    }    for(int i=0;i<n;i++)    {        int sz=begin[i].size();        for(int j=0;j<sz;j++)            for(int k=0;k<sz;k++)                if((begin[i][k]^end[i][j])!=1)                    B.m[end[i][j]][begin[i][k]]++;    }    int sz=begin[S].size();    for(int i=0;i<sz;i++)        A.m[0][begin[S][i]]++;    B=pow(B,t-1);    A=mul(A,B);    sz=end[T].size();    for(int i=0;i<sz;i++)        for(int k=0;k<=cnt;k++)            ans=(ans+A.m[k][end[T][i]])%mod;    cout<<ans;    return 0;} 
原创粉丝点击