Luo Gu P2939 [USACO09FEB] Remaking Revamping Trails
Description
John, a total of N) ranch. Covered by the dust of the M trail connection. Trails can be two-way traffic. Every morning John from ranch to ranch 1 to N cows physical examination.
Trail through each need to consume some time. John K which intend to upgrade the trail, making it a highway. Traffic on the highway is almost instantaneous, so the passage of time the highway is zero.
Please help John to decide which trails to upgrade, so that he daily from No. 1 to No. N ranch pasture spent the shortest
Input
* Line 1: Three space-separated integers: N, M, and K
* Lines 2..M+1: Line i+1 describes trail i with three space-separated integers: P1_i, P2_i, and T_i
Output
- Line 1: The length of the shortest path after revamping no more than K edges
Data Size
- 1 <= N <= 10,000
- 1 <= M <= 50,000
- 1 <= T_i <= 1,000,000
- 1 <= K <= 20
answer:
- Layered graph.
- It is easy to see. It is actually a template. The principle is to build k + 1 map. The first layer is a picture, the second layer is a "divine" FIG third layer twice with "Divine" ... ... FIG. Shortest can run after completing construction of Fig.
#include <iostream>
#include <cstdio>
#include <queue>
#include <cstring>
#define N 10005 * 42
#define M 100005 * 42
using namespace std;
struct Node
{
int val, pos;
friend bool operator < (Node x, Node y) {
return x.val > y.val;
}
};
priority_queue<Node> que;
struct E {int next, to, dis;} e[M];
int n, m, k, num, ans = 0x7fffffff;
int dis[N], h[N];
bool vis[N];
int read()
{
int x = 0; char c = getchar();
while(c < '0' || c > '9') c = getchar();
while(c >= '0' && c <= '9') {x = x * 10 + c - '0'; c = getchar();}
return x;
}
void add(int u, int v, int w)
{
e[++num].next = h[u];
e[num].to = v;
e[num].dis = w;
h[u] = num;
}
int main()
{
cin >> n >> m >> k;
for(int i = 1; i <= m; i++)
{
int u = read(), v = read(), w = read();
add(u, v, w), add(v, u, w);
for(int j = 1; j <= k; j++)
{
add(u + j * n, v + j * n, w);
add(v + j * n, u + j * n, w);
add(u + (j - 1) * n, v + j * n, 0);
add(v + (j - 1) * n, u + j * n, 0);
}
}
memset(dis, 0x3f, sizeof(dis));
dis[1] = 0, que.push((Node){0, 1});
while(que.size())
{
int now = que.top().pos;
que.pop();
if(vis[now]) continue;
vis[now] = 1;
for(int i = h[now]; i != 0; i = e[i].next)
if(dis[now] + e[i].dis < dis[e[i].to])
{
dis[e[i].to] = dis[now] + e[i].dis;
que.push((Node){dis[e[i].to], e[i].to});
}
}
for(int i = 0; i <= k; i++) ans = min(ans, dis[n + i * n]);
cout << ans;
return 0;
}