(最短路+拆点)Rinne Loves Graph
https://ac.nowcoder.com/acm/problem/22594
\(拆点\)
\(把每个点拆分成下标和经过的次数然后做一遍dijkstra即可\)
\(为了表示拆出的点,dist[]和st[]都要升维,每个点有三个元素:id,cnt,dis\)
#include <bits/stdc++.h>
using namespace std;
#define IO ios::sync_with_stdio(false);cin.tie(0); cout.tie(0);
inline int lowbit(int x) { return x & (-x); }
#define ll long long
#define ull unsigned long long
#define pb push_back
#define PII pair<int, int>
#define VIT vector<int>
#define x first
#define y second
#define inf 0x3f3f3f3f
const int N = 810, M = 8010, K = 15;
int n, m, k;
int a[N];
int h[N], ne[M], w[M], e[M], idx;
bool st[N][K];
ll dist[N][K];
void add(int a, int b, int c) {
e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx++;
}
struct Node {
int id, k;
ll dis;
bool operator < (const Node &t) const {
return dis > t.dis;
}
};
void dijkstra() {
memset(dist, 0x3f, sizeof dist);
priority_queue<Node> q;
dist[1][0] = 0;
q.push({1, 0, 0});
while (q.size()) {
Node t = q.top();
q.pop();
int id = t.id, cnt = t.k;
ll dis = t.dis;
if (st[id][cnt]) continue;
st[id][cnt] = 1;
for (int i = h[id]; ~i; i = ne[i]) {
int j = e[i];
int tk = a[id] + cnt;
if (tk <= k && dist[j][tk] > dis + w[i]) {
dist[j][tk] = dis + w[i];
q.push({j, tk, dist[j][tk]});
}
}
}
}
int main() {
//freopen("in.txt", "r", stdin);
memset(h, -1, sizeof h);
IO;
cin >> n >> m >> k;
for (int i = 1; i <= n; ++i) cin >> a[i];
while(m--) {
int a, b, c;
cin >> a >> b >> c;
add(a, b, c), add(b, a, c);
}
dijkstra();
ll ans = inf;
for (int i = 0; i <= k; ++i) ans = min(ans, dist[n][i]);
if (ans == inf) cout << "-1\n";
else cout << ans << '\n';
return 0;
}