describe
There are NN cities in the country, and MM directional roads from uu to v(1\le u, v\le n)v(1≤u,v≤n). Every road has a distance c_ici. Haze is a Magical Girl that lives in City 11, she can choose no more than KK roads and make their distances become 00. Now she wants to go to City NN, please help her calculate the minimum distance.
Input
The first line has one integer T(1 \le T\le 5)T(1≤T≤5), then following TT cases.
For each test case, the first line has three integers N, MN,M and KK.
Then the following MM lines each line has three integers, describe a road, U_i, V_i, C_iUi,Vi,Ci. There might be multiple edges between uu and vv.
It is guaranteed that N \le 100000, M \le 200000, K \le 10N≤100000,M≤200000,K≤10,
0 \le C_i \le 1e90≤Ci≤1e9. There is at least one path between City 11 and City NN.
Output
For each test case, print the minimum distance.
sample input
1 5 6 1 1 2 2 1 3 4 2 4 3 3 4 1 3 5 6 4 5 2
sample output
3
Source of title
ACM-ICPC 2018 Nanjing Area Network Preliminary Competition
thinking
Given a directed graph with mm edges of nn points, from 11 points to nn points, there is a kk chance to make the cost of one edge change to 00, and the minimum cost from 11 to nn is obtained.
Subject meaning and sum BZOJ2763 flight route (layered shortest path, dijkstra heap optimization) It's exactly the same. It's the shortest path in layers.
We need to use ideas like dynamic programming to transfer.
We define:
- dis[i][j]dis[i][j]: From the starting point st to point i, the minimum cost of using J preferential opportunities is used.
- vis[i][j]vis[i][j]: from point st to point i, is the status of using J preferential opportunities marked?
We need to make some changes to the ordinary Dijstra transfer:
-
When free opportunities are not used:
If the cost of arrival u is dis[u][k] + the edge weight W < to the edge weight dis[v][k] from u to V Normal metastasis update: dis[v][k]=dis[u][k]+w Add heap q.push(node(v,k,dis[v][k])
-
When using free opportunities:
If the cost of K opportunities is dis [u] [k] < the edge weight dis[v][k+1] of k+1 opportunities is used at point u This side is free to update dis[v][k+1]=dis[u][k] Add heap q.push(node(v,k+1,dis[v+1][k])
All that's left is Diegerstella's heap optimization template.
Code
#include <bits/stdc++.h>
using namespace std;
#define mem(a, b) memset(a, b, sizeof(a))
const int inf = 0x3f3f3f3f;
const int N = 1e5 + 10;
int first[N], tot;
int n, m, k;
struct edge
{
int v, w, next;
} e[N * 2];
void add_edge(int u, int v, int w)
{
e[tot].v = v, e[tot].w = w;
e[tot].next = first[u];
first[u] = tot++;
}
void init()
{
mem(first, -1);
tot = 0;
}
struct node
{
int id, k, now;
node() {}
node(int _id, int _k, int _now)
{
id = _id, k = _k, now = _now;
}
bool friend operator<(node a, node b)
{
return a.now > b.now;
}
};
int dis[N][12], vis[N][12];
void dijkstra(int st)
{
for (int i = 1; i <= n; i++)
{
for (int j = 0; j <= k; j++)
{
dis[i][j] = inf;
vis[i][j] = 0;
}
}
dis[st][0] = 0;
priority_queue<node> q;
q.push(node(st, 0, 0));
while (!q.empty())
{
node u = q.top();
q.pop();
if (!vis[u.id][u.k])
{
vis[u.id][u.k] = 1;
for (int i = first[u.id]; ~i; i = e[i].next)
{
int v = e[i].v, w = e[i].w;
if (!vis[v][u.k] && dis[u.id][u.k] + w < dis[v][u.k])
{
dis[v][u.k] = dis[u.id][u.k] + w;
q.push(node(v, u.k, dis[v][u.k]));
}
if (u.k < k && !vis[v][u.k] && dis[u.id][u.k] < dis[v][u.k + 1])
{
dis[v][u.k + 1] = dis[u.id][u.k];
q.push(node(v, u.k + 1, dis[v][u.k + 1]));
}
}
}
}
}
void solve()
{
int u, v, w;
scanf("%d%d%d", &n, &m, &k);
init();
for (int i = 1; i <= m; i++)
{
scanf("%d%d%d", &u, &v, &w);
add_edge(u, v, w);
}
dijkstra(1);
int ans = inf;
for (int i = 0; i <= k; i++)
ans = min(ans, dis[n][i]);
printf("%d\n", ans);
}
int main()
{
//freopen("in.txt", "r", stdin);
int t;
scanf("%d", &t);
while (t--)
solve();
return 0;
}