洛谷P2886 [USACO07NOV]Cow Relays G (矩阵乘法与路径问题)
本题就是求两点间只经过n条边的最短路径,定义广义的矩阵乘法,就是把普通的矩阵乘法从求和改成了取最小值,把内部相乘改成了相加。
代码包含三个内容:广义矩阵乘法,矩阵快速幂,离散化;
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int N = 120, inf = 0x3f3f3f3f; 4 int Hash[1000005], cnt; 5 struct matrix { 6 int m[N][N]; 7 }ans, a; 8 matrix operator * (const matrix &a, const matrix &b) {//定义广义矩阵乘法 9 matrix c; 10 memset(c.m, inf, sizeof c.m); 11 for (int i = 1; i <= cnt; i ++) 12 for (int j = 1; j <= cnt; j ++) 13 for(int k = 1; k <= cnt; k ++) 14 c.m[i][j] = min(c.m[i][j], a.m[i][k] + b.m[k][j]); 15 return c; 16 } 17 matrix pow_matrix(matrix a, int n) { 18 ans = a; n --; 19 while (n) { 20 if (n & 1) ans = ans * a; 21 a = a * a; 22 n >>= 1; 23 } 24 return ans; 25 } 26 int main() { 27 int n, t, s, e; 28 cin >> n >> t >> s >> e; 29 memset(a.m, inf, sizeof a.m); 30 while (t --) { 31 int u, v, w; 32 cin >> w >> u >> v; 33 if (!Hash[u]) Hash[u] = ++ cnt; 34 if (!Hash[v]) Hash[v] = ++ cnt; 35 a.m[Hash[u]][Hash[v]] = a.m[Hash[v]][Hash[u]] = w; 36 } 37 ans = pow_matrix(a, n); 38 cout << ans.m[Hash[s]][Hash[e]]; 39 return 0; 40 }