Blog of RuSun

\begin {array}{c} \mathfrak {One Problem Is Difficult} \\\\ \mathfrak {Because You Don't Know} \\\\ \mathfrak {Why It Is Diffucult} \end {array}

P2886 [USACO07NOV]Cow Relays G

P2886 [USACO07NOV]Cow Relays G

虽然叫做矩阵加速,但是很不一样。

初始矩阵中的初始化,$f _ {i, i} = 0$ ,但是计算中不允许一个点不动,即必须经过一些边,这样自己到自己的最短路就不再是 $0$ ,所以为 $inf$ 。

查看代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
using namespace std;
const int N = 210, inf = 1e9;
int n, t, m, st, ed;
struct Edge
{
int u, v, w;
} e[N];
map<int, int> f;
struct Matrix
{
int m[N][N];
void reset()
{
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
m[i][j] = inf;
}
Matrix operator*(Matrix _)
{
Matrix C;
C.reset();
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
for (int k = 1; k <= n; k++)
C.m[i][j] = min(C.m[i][j], m[i][k] + _.m[k][j]);
return C;
}
} A, B;
int get(int x)
{
if (f.count(x))
return f[x];
return f[x] = ++n;
}
int main()
{
scanf("%d%d%d%d", &t, &m, &st, &ed);
for (int i = 1, u, v; i <= m; i++)
{
scanf("%d%d%d", &e[i].w, &u, &v);
u = get(u);
v = get(v);
e[i].u = u, e[i].v = v;
}
A.reset(), B.reset();
for (int i = 1; i <= n; i++)
A.m[i][i] = 0;
for (int i = 1; i <= m; i++)
{
int u = e[i].u, v = e[i].v, w = e[i].w;
B.m[u][v] = B.m[v][u] = min(B.m[u][v], w);
}
while (t)
{
if (t & 1)
A = A * B;
B = B * B;
t >>= 1;
}
printf("%d", A.m[get(st)][get(ed)]);
return 0;
}