zl程序教程

您现在的位置是:首页 >  其它

当前栏目

商人的宣传

宣传
2023-09-27 14:28:29 时间

商人的宣传

题目链接:jzoj 1047

题目大意

有一个图,有很多个询问,每个询问问你从某个点一定走固定的步数恰好走到另一个点有多少种方案。

思路

这道题点的个数,要走的步数都小于等于 100,可以想到要用矩阵乘法。

那怎么用呢?
我们可以用一个矩阵表示当前从某个点走一步到某个点的方案数,然后如果两个一样的乘在一起,就是走两步到的方案。
那以此类推,我们就可以得出走某个固定步数,每两个点之间能够到达的方案数。

但是一开始的矩阵怎么建呢?
那其实就是把给的边建一个邻接矩阵,边距离为 1。

然后把 L 个矩阵乘起来,就是答案了。

代码

#include<cstdio>

using namespace std;

struct matrix {
	int n, m;
	long long a[101][101];
}a, b, ans, re;
int n, m, l, q, A, B;

matrix operator *(matrix x, matrix y) {
	re.n = x.n;
	re.m = y.m;
	for (int i = 1; i <= re.n; i++)
		for (int j = 1; j <= re.m; j++)
			re.a[i][j] = 0;
	
	for (int k = 1; k <= x.m; k++)
		for (int i = 1; i <= re.n; i++)
			for (int j = 1; j <= re.m; j++)
				re.a[i][j] = re.a[i][j] + x.a[i][k] * y.a[k][j];
	
	return re;
}

void jzksm(int now) {
	b = a;
	now--;
	while (now) {
		if (now & 1) b = b * a;
		a = a * a;
		now /= 2;
	}
}

int main() {
	scanf("%d %d %d", &n, &m, &l);
	
	a.n = n;//建矩阵
	a.m = n;
	for (int i = 1; i <= m; i++) {
		scanf("%d %d", &A, &B);
		a.a[A][B] = 1ll;
	}
	
	jzksm(l);
	
	scanf("%d", &q);
	for (int i = 1; i <= q; i++) {
		scanf("%d %d", &A, &B);
		printf("%lld\n", b.a[A][B]);
	}
	
	return 0;
}