思路:用邻接矩阵存储图,然后矩阵的k次方即为答案。只需要修改矩阵乘法c[i][j] = min(c[i][j], a[i][k] +
b[k][j])即可。并不难写关键是思路。
代码如下:
1 #include <stdio.h>
2 #include <string.h>
3 #include <iostream>
4 #include <algorithm>
5 #include <vector>
6 #include <queue>
7 #include <set>
8 #include <map>
9 #include <string>
10 #include <math.h>
11 #include <stdlib.h>
12 #include <time.h>
13 using namespace std;
14
15 const int LEN = 51;
16 typedef long long ll;
17 const ll LINF = 0x3f3f3f3f3f3f3f3fLL;
18 int n, h, k;
19
20
21 void debug(ll Mix[][LEN]){
22 for(int i=0; i<n; i++){
23 for(int j=0; j<n; j++){
24 if(Mix[i][j] != LINF)cout << Mix[i][j] << ‘ ‘ ;
25 else cout << "- ";
26 }
27 cout << endl;
28 }cout << endl;
29 }
30
31 void Mul(ll a[][LEN], ll b[][LEN]){
32 ll c[LEN][LEN];
33 memset(c, 0x3f, sizeof c);
34 for(int i=0; i<n; i++){
35 for(int j=0; j<n; j++){
36 for(int k=0; k<n; k++){
37 if(a[i][k] == LINF || b[k][j] == LINF) continue;
38 c[i][j] = min(c[i][j], a[i][k] + b[k][j]);
39 }
40 }
41 }
42 // debug(a); debug(b);debug(c);
43 for(int i=0; i<n; i++){
44 for(int j=0; j<n; j++){
45 a[i][j] = c[i][j];
46 }
47 }
48 }
49
50 void Mksm(ll t[][LEN], int k){
51 ll Mix[LEN][LEN];
52 for(int i=0; i<n; i++)
53 for(int j=0; j<n; j++)
54 Mix[i][j] = (i==j ? 0 : LINF);
55 while(k){
56 if(k & 1) Mul(Mix, t);
57 Mul(t, t);
58 k >>= 1;
59 }
60 for(int i=0; i<n; i++)
61 for(int j=0; j<n; j++)
62 t[i][j] = Mix[i][j];
63 }
64
65
66 int main()
67 {
68 // freopen("in.txt","r",stdin);
69 //freopen("out.txt","w",stdout);
70
71 int T, a, b, val;
72 ll Mix[LEN][LEN];
73 cin >> T;
74 while(T--){
75 memset(Mix, 0x3f, sizeof Mix);
76 cin >> n >> h >> k;
77 for(int i=0; i<h; i++){
78 cin >> a >> b >> val;
79 a--, b--;
80 Mix[a][b] = val;
81 }
82 Mksm(Mix, k);
83 if(Mix[0][n-1] != LINF) cout << Mix[0][n-1] << endl;
84 else cout << -1 << endl;
85 }
86 return 0;
87 }
fzuoj 2173(矩阵快速幂),布布扣,bubuko.com
时间: 2024-12-13 12:06:12