题解 P2829 大逃离
直接根据题意把度数 \(<k\) 的点标记成不能走,然后求次短路即可。
注意重边和自环,代码如下:
#include <cstdio>
#include <cstring>
#include <cctype>
#include <algorithm>
#include <iostream>
#include <queue>
#include <map>
typedef long long LL;
using namespace std;
inline int read() {
int num = 0 ,f = 1; char c = getchar();
while (!isdigit(c)) f = c == '-' ? -1 : f ,c = getchar();
while (isdigit(c)) num = (num << 1) + (num << 3) + (c ^ 48) ,c = getchar();
return num * f;
}
const int N = 5e3 + 5 ,M = 2e5 + 5;
const LL INF = 0x3f3f3f3f3f3f3f3f;
struct Edge {
int to ,w ,next;
Edge (int to = 0 ,int w = 0 ,int next = 0) : to(to) ,w(w) ,next(next) {}
}G[M]; int head[N] ,idx;
inline void add(int u ,int v ,int w) {
G[++idx] = Edge(v ,w ,head[u]); head[u] = idx;
G[++idx] = Edge(u ,w ,head[v]); head[v] = idx;
}
struct node {
int id; LL dis;
node (int id = 0 ,LL dis = 0) : id(id) ,dis(dis) {}
friend bool operator < (const node &a ,const node &b) {
return a.dis > b.dis;
}
};
LL dis[N] ,cdis[N]; int done[N]; bool used[N];
inline void dijkstra(int n ,int s) {
for (int i = 1; i <= n; i++)
dis[i] = cdis[i] = INF ,done[i] = 0;
priority_queue <node> q;
q.push(node(s ,0)); dis[s] = 0;
while (!q.empty()) {
int now = q.top().id ,dist = q.top().dis; q.pop();
if (done[now] > 1) continue;
done[now]++;
for (int i = head[now]; i ; i = G[i].next) {
int v = G[i].to ,w = G[i].w;
if (done[v] > 1 || used[v]) continue;
if (dis[v] > dist + w) {
cdis[v] = dis[v] ,dis[v] = dist + w;
q.push(node(v ,dis[v]));
}
else if (cdis[v] > dist + w) {
cdis[v] = dist + w;
q.push(node(v ,cdis[v]));
}
}
}
}
int n ,m ,k ,rd[N];
map <pair <int ,int> ,int> mp;
signed main() {
n = read() ,m = read() ,k = read();
for (int i = 1; i <= m; i++) {
int u = read() ,v = read() ,w = read();
add(u ,v ,w);
if (u != v && !mp[make_pair(u ,v)])
rd[u]++ ,rd[v]++ ,mp[make_pair(u ,v)] = true ,mp[make_pair(v ,u)] = true;
}
for (int i = 1; i <= n; i++) if (rd[i] < k) used[i] = true;
used[1] = used[n] = false;
dijkstra(n ,1);
printf("%lld\n" ,cdis[n] == INF ? -1 : cdis[n]);
return 0;
}