bzoj1297: [SCOI2009]迷路

题解

若边权为1就是个矩阵快速幂裸题
因为权值<=10 ,对于每个点拆成9个点权值t就可以用t条权值为1的边表示

代码

/*
*/
#include<cstdio> 
#include<cstring> 
#include<algorithm> 
inline int read() { 
	int x = 0,f = 1; 
	char c = getchar(); 
	while(c < '0' || c > '9')c = getchar(); 
	while(c <= '9' && c >= '0') x = x * 10 + c - '0',c = getchar(); 
	return x * f; 
} 
const int mod = 2009; 
int n,t; 
struct Matrix { 
	int a[107][107]; 
	Matrix() {memset(a,0,sizeof a); } 
	Matrix operator * (const Matrix &b) const { 
		Matrix ret; 
		for(int k = 1;k <= n;++ k) 	
			for(int i = 1;i <= n;++ i) 
				for(int j = 1;j <= n;++ j) 
				ret.a[i][j] = (ret.a[i][j] + a[i][k] * b.a[k][j]) % mod; 
		return ret; 
	} 
} a; 
Matrix fstpow(int k) { 
	Matrix ret; 
	for(int i = 1;i <= n;++ i)ret.a[i][i] = 1; 
	for(;k;k >>= 1,a = a * a) 
		if(k & 1) ret = ret * a; 
	return ret; 
} 
int main() { 
	n = read(),t = read(); 
	for(int i = 1;i <= n;++ i) 
		for(int j = 9;j > 1;-- j) 
			a.a[(i - 1) * 9 + j][9 * (i - 1) + j - 1] = 1; 
	static char s[40]; 
	for(int i = 1;i <= n;++ i) { 
		scanf("%s",s + 1); 
		for(int j = 1;j <= n;++ j) { 
			int t = s[j] - '0'; 
			if(t) a.a[(i - 1) * 9 + 1][(j - 1) * 9 + t] = 1; 
		} 
	} 
	n *= 9; //for(int i = 1;i <= n;++ i) { for(int j = 1;j <= n;++ j) printf("%d ",a.a[i][j]); puts(""); } 
	Matrix ans = fstpow(t); 
	printf("%d\n",ans.a[1][n - 8]); 
	return 0; 
} 

相关文章:

  • 2021-07-03
  • 2021-09-09
  • 2021-12-05
  • 2022-12-23
  • 2021-10-19
  • 2021-08-29
  • 2021-09-15
猜你喜欢
  • 2021-08-18
  • 2021-12-19
  • 2022-02-03
  • 2022-01-27
  • 2021-12-18
  • 2021-06-03
  • 2021-07-31
相关资源
相似解决方案