洛谷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 }

 

posted @ 2022-04-29 21:35  YHXo  阅读(30)  评论(0编辑  收藏  举报