[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 = ans * x; 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; }