【SCOI2009】迷路

题面

题解

如果给我们的是一个邻接矩阵,那么直接给邻接矩阵(T)次幂即可。

这里的图有边权,那么我们就将它拆成(9)个点即可。

代码

#include<cstdio>
#include<cstring>
#include<algorithm>
#define RG register
#define file(x) freopen(#x".in", "r", stdin);freopen(#x".out", "w", stdout);

inline int read()
{
	int data = 0, w = 1;
	char ch = getchar();
	while(ch != '-' && (ch < '0' || ch > '9')) ch = getchar();
	if(ch == '-') w = -1, ch = getchar();
	while(ch >= '0' && ch <= '9') data = data * 10 + (ch ^ 48), ch = getchar();
	return data * w;
}

inline int read_char()
{
	char ch = getchar();
	while(ch < '0' || ch > '9') ch = getchar();
	return (ch ^ 48);
}

const int maxn(110), Mod(2009);

int n, T;
inline int Num(const int &x, const int &y) { return x + y * n; }

struct Matrix
{
	int a[maxn][maxn], n;
	Matrix(int n = 0) : n(n) { memset(a, 0, sizeof(a)); }

	inline int *operator [] (const int &id) { return a[id]; }
	inline Matrix operator * (const Matrix &b)
	{
		Matrix c(n);
		for(RG int i = 1; i <= n; i++)
			for(RG int j = 1; j <= n; j++)
				for(RG int k = 1; k <= n; k++)
					c[i][k] = (c[i][k] + a[i][j] * b.a[j][k]) % Mod;
		return c;
	}
};

int main()
{
	n = read(); T = read();
	Matrix S(n * 9), A(n * 9);
	for(RG int i = 1; i <= n; i++)
	{
		for(RG int j = 1; j < 9; j++)
			S[Num(i, j)][Num(i, j - 1)] = 1;
		for(RG int j = 1, x; j <= n; j++)
			if((x = read_char())) S[i][Num(j, x - 1)] = 1;
	}

	for(RG int i = 1; i <= A.n; i++) A[i][i] = 1;
	while(T) { if(T & 1) A = A * S; S = S * S, T >>= 1; }
	printf("%d
", A[1][n]);
	return 0;
}
原文地址:https://www.cnblogs.com/cj-xxz/p/9879910.html