[luoguP2886] [USACO07NOV]牛继电器Cow Relays(矩阵)

Posted 蒟蒻zht的博客

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[luoguP2886] [USACO07NOV]牛继电器Cow Relays(矩阵)相关的知识,希望对你有一定的参考价值。

传送门

 

矩阵快速幂,本质是floyd

把 * 改成 + 即可

注意初始化

 

因为只有100条边,所以可以离散化

 

#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 101
#define min(x, y) ((x) < (y) ? (x) : (y))

int n, t, s, e, cnt;
int x[N], y[N], z[N], a[N];

struct Matrix
{
	int n, m;
	int a[N][N];
	Matrix()
	{
		n = m = 0;
		memset(a, 63, sizeof(a));
	}
};

inline Matrix operator * (Matrix x, Matrix y)
{
	int i, j, k;
	Matrix ans;
	ans.n = x.n;
	ans.m = y.m;
	for(i = 1; i <= x.n; i++)
		for(j = 1; j <= y.m; j++)
			for(k = 1; k <= y.n; k++)
				ans.a[i][j] = min(ans.a[i][j], x.a[i][k] + y.a[k][j]);
	return ans;
}

inline Matrix operator ^ (Matrix x, int y)
{
	int i;
	Matrix ans;
	ans.n = ans.m = cnt;
	for(i = 1; i <= cnt; i++) ans.a[i][i] = 0;
	for(; y; y >>= 1)
	{
		if(y & 1) ans = x * ans;
		x = x * x;
	}
	return ans;
}

int main()
{
	int i;
	Matrix sum;
	scanf("%d %d %d %d", &n, &t, &s, &e);
	a[++cnt] = s;
	a[++cnt] = e; 
	for(i = 1; i <= t; i++)
	{
		scanf("%d %d %d", &z[i], &x[i], &y[i]);
		a[++cnt] = x[i];
		a[++cnt] = y[i];
	}
	std::sort(a + 1, a + cnt + 1);
	cnt = std::unique(a + 1, a + cnt + 1) - (a + 1);
	sum.n = sum.m = cnt;
	for(i = 1; i <= t; i++)
	{
		x[i] = std::lower_bound(a + 1, a + cnt + 1, x[i]) - a;
		y[i] = std::lower_bound(a + 1, a + cnt + 1, y[i]) - a;
		sum.a[x[i]][y[i]] = z[i];
		sum.a[y[i]][x[i]] = z[i];
	}
	sum = sum ^ n;
	s = std::lower_bound(a + 1, a + cnt + 1, s) - a;
	e = std::lower_bound(a + 1, a + cnt + 1, e) - a;
	printf("%d\n", sum.a[s][e]);
	return 0;
}

  

以上是关于[luoguP2886] [USACO07NOV]牛继电器Cow Relays(矩阵)的主要内容,如果未能解决你的问题,请参考以下文章

Luogu P2886 [USACO07NOV]牛继电器Cow Relays|最短路,倍增

[luoguP2885] [USACO07NOV]电话线Telephone Wire(DP + 贪心)

[USACO07NOV]牛继电器Cow Relays

题解Luogu P2889 [USACO07NOV]挤奶的时间Milking Time

LuoguP6218 [USACO06NOV] Round Numbers S

[luoguP1879] [USACO06NOV]玉米田Corn Fields(DP)