[BZOJ 1875] SDOI 2009 HH去散步 · 矩阵乘法

来源:互联网 发布:mac命令行安装mysql 编辑:程序博客网 时间:2024/05/29 09:15

矩阵乘法。

这题等于是VJ1603的略强化版,就是多了个不允许走回头路,我们把一条双向边建成两条方向相反的单向边,和网络流的建边一个方法,然后直接二维扫一遍建矩阵,a[i][j]=1表示从i号边下一步可以走到j号边,然后就做矩乘啦~然后再二维扫一遍出答案啦~然后笔者就妥妥的TLE啦~

当时看到TLE也是吓的不轻,实在是想不懂这种复杂度怎么会超时……然后就加了个读入优化顺便删掉iostream库再交上去:

这个故事告诉我们一个道理:刷八中不能用cin(这题用scanf一样过)

#include <stdio.h>#include <algorithm>#include <string.h>using namespace std;#define p 45989const int maxn=150;int n,m,k,s,t,x[maxn],y[maxn];struct matrix{int num[maxn][maxn];void init(){memset(num,0,sizeof num);}}a,ans;int get(){int s=0;char x=getchar();while (x<'0' || x>'9') x=getchar();while (x>='0' && x<='9') s=s*10+x-'0',x=getchar();return s;}void init(){n=get();m=get();k=get();s=get();t=get();for (int i=0;i<m;i++){x[i+i]=get();y[i+i]=get();x[i+i+1]=y[i+i];y[i+i+1]=x[i+i];}m=m+m-1;}matrix operator *(matrix a,matrix b){matrix c;c.init();for (int i=0;i<=m;i++)for (int j=0;j<=m;j++)for (int t=0;t<=m;t++)c.num[i][j]=(c.num[i][j]+a.num[i][t]*b.num[t][j])%p;return c;}int main(){init();a.init();for (int i=0;i<=m;i++)for (int j=0;j<=m;j++)if ((i^1)!=j && y[i]==x[j]) a.num[i][j]++;for (int i=0;i<=m;i++) ans.num[i][i]=1;for (k--;k;k>>=1,a=a*a)if (k&1) ans=ans*a;int calc=0; for (int i=0;i<=m;i++)for(int j=0;j<=m;j++)if (x[i]==s && y[j]==t) calc=(calc+ans.num[i][j])%p;printf("%d\n",calc);return 0;}


0 0
原创粉丝点击