首页 > 代码库 > BZOJ 1875 SDOI 2009 HH去散步 矩阵乘法优化DP
BZOJ 1875 SDOI 2009 HH去散步 矩阵乘法优化DP
题目大意:给出一张无向图,求从A到B走k步(不能走回头路)的方案数。(k <= 2^30)
思路:看到k的范围就知道是矩阵乘法了。关键是不能走回头路怎么构造。正常的方法构造点的转移不能避免这个问题,就用边来构造。只要保证不经过自己^1的边就可以保证不走回头路了。
CODE:
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define MAX 210 #define MO 45989 using namespace std; int total = 1; struct Matrix{ int num[MAX][MAX]; Matrix() { memset(num,0,sizeof(num)); } Matrix operator *(const Matrix &a)const { Matrix re; for(int i = 0; i <= total; ++i) for(int j = 0; j <= total; ++j) for(int k = 0; k <= total; ++k) { re.num[i][j] += num[i][k] * a.num[k][j]; re.num[i][j] %= MO; } return re; } }src,ans,temp; int points,edges,t; int S,T; int head[MAX]; int next[MAX],aim[MAX]; inline void Add(int x,int y) { next[++total] = head[x]; aim[total] = y; head[x] = total; } int stack[MAX],top; int main() { cin >> points >> edges >> t >> S >> T; ++S,++T; for(int x,y,i = 1; i <= edges; ++i) { scanf("%d%d",&x,&y); x++,y++; Add(x,y),Add(y,x); } for(int i = head[S]; i; i = next[i]) ans.num[0][i] = 1; for(int i = 2; i <= total; ++i) { int x = aim[i]; if(x == T) stack[++top] = i; for(int j = head[x]; j; j = next[j]) { if(j == (i^1)) continue; src.num[i][j] = 1; } } for(int i = 0; i <= total; ++i) temp.num[i][i] = 1; --t; while(t) { if(t&1) temp = temp * src; src = http://www.mamicode.com/src * src;>BZOJ 1875 SDOI 2009 HH去散步 矩阵乘法优化DP
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。