您的位置:首页 > 其它

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

2015-04-01 23:00 351 查看
矩阵乘法。

这题等于是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 45989

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