题解 P6190 【[NOI Online 入门组]魔法(民间数据)】
这题其实考察了一个小
这个
对于一个邻接矩阵
G ,那么G^k 表示的就是恰好经过k 后的状态。
举一个比较简单的例子:
#define int long long
const int N = 105;
const int M = 2505;
int n, m, kk;
struct Matrix {
int a[N][N];
int* operator[](int i) {
return a[i];
}
Matrix operator*(Matrix oth) {
Matrix res;
memset(res.a, 0x3f, sizeof res.a);
For (k, 0, n - 1) {
For (i, 0, n - 1) {
For (j, 0, n - 1) {
chkmin(res[i][j], a[i][k] + oth[k][j]);
}
}
}
return res;
}
friend Matrix operator^(Matrix x, int idx) {
Matrix res = x;
idx--;
for (; idx; idx >>= 1, x = x * x) {
if (idx & 1) {
res = res * x;
}
}
return res;
}
};
struct Path {
int u, v, t;
} path[M];
int g[N][N];
signed main() {
memset(g, 0x3f, sizeof g);
read(n), read(m), read(kk);
For (i, 0, m - 1) {
read(path[i].u), read(path[i].v), read(path[i].t);
path[i].u--, path[i].v--;
g[path[i].u][path[i].v] = path[i].t;
}
For (i, 0, n - 1) {
g[i][i] = 0;
}
For (k, 0, n - 1) {
For (i, 0, n - 1) {
For (j, 0, n - 1) {
chkmin(g[i][j], g[i][k] + g[k][j]);
}
}
}
Matrix base;
memset(base.a, 0x3f, sizeof base.a);
For (i, 0, n - 1) {
base[i][i] = 0;
}
For (i, 0, m - 1) {
int u = path[i].u, v = path[i].v, t = path[i].t;
For (j, 0, n - 1) {
For (k, 0, n - 1) {
chkmin(base[j][k], g[j][u] - t + g[v][k]);
}
}
}
if (kk) {
writeln((base ^ kk)[0][n - 1]);
} else {
writeln(g[0][n - 1]);
}
return 0;
}