牛客第四场 J题 free 分层图

题意

题目链接

给你一个图,但是可以把其中某条路的k条边的权值设置为0,问最短路的长度是多少。

思路

可以构建分层图, 每一层之间都是单向路径,而且长度为0,跑一遍dijkstra即可。

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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <bitset>
typedef long long ll;
using namespace std;


struct node{
int v, w, next;
}edge[5000005];
const int inf = 0x3f3f3f3f;
const int maxn = 5e6 + 10000;
int tot = 0, head[maxn], vis[maxn], dist[maxn];
void add(int u, int v, int w)
{
edge[++tot].v = v;
edge[tot].w = w;
edge[tot].next = head[u];
head[u] = tot;
}
priority_queue<pair<int,int> >Q;
void dijkstra(int S)
{
Q.push({-0, S});
dist[S] = 0;
while(!Q.empty())
{
int u = Q.top().second;
Q.pop();
if(vis[u])continue;
vis[u] = 1;
for(int k = head[u]; k != -1; k = edge[k].next)
{
int v = edge[k].v;
int w = edge[k].w;
if(dist[v] > dist[u] + w)
{
dist[v] = dist[u] + w;
Q.push({-dist[v], v});
}

}
}
}
const int N = 1000;
int main()
{
int n, m, S, T, k,u, v, w;
cin >> n >> m >> S >> T >> k;
memset(dist, inf, sizeof(dist));
memset(head, -1, sizeof(head));
for(int i = 1; i <= m; ++i)
{
scanf("%d%d%d",&u,&v,&w);
add(u, v, w);
add(v, u, w);
for(int j = 1; j <= k; ++j)
{
add(u + (j-1) * N,v + j * N, 0);
add(v + (j-1) * N , u + j * N, 0);
add(u + j * N , v + j * N, w);
add(v + j * N, u + j * N, w);
}
}
dijkstra(S);
int Min = inf;
for(int i = 0; i <= k; ++i)
{
Min = min(Min, dist[T + i * N]);
}
cout << Min <<'\n';
return 0;
}