最短路简单题——[USACO09FEB]Revamping Trails G
作者:互联网
题目大意:给定n个点,m条边的无向图,可以让任意k条边的边权变为0,求从1号点到n号点的最短路。
思路:分层图板题,思路如下:
我们把这个图复制成k+1层图,每一层都与原来的无向图相同,但是任两层图之间的边权为0。思考到一个性质,即因为两层图之间建的是单向图,所以最多只会走k条边权为0的边,走到第i层即说明已经使用了i-1次将边权变为0的机会,所以我们通过分层图的思想把这样一个题变成了最短路板题。下面是代码:
#include <bits/stdc++.h> using namespace std; typedef pair <int, int> P; priority_queue <P, vector <P>, greater <P> > Q; struct node { int to, nxt, len; }e[5000005]; int head[2500005], dis[2500005], vis[2500005], tot; inline void add_e(int u, int v, int w) {e[++tot].to = v; e[tot].nxt = head[u]; head[u] = tot; e[tot].len = w;} void dijkstra(int s) { memset(dis, 0x3f, sizeof dis); dis[s] = 0; Q.push(make_pair(0, s)); while (!Q.empty()) { int u = Q.top().second; Q.pop(); if (vis[u]) continue; else vis[u] = 1; for (int i = head[u]; i; i = e[i].nxt) { int v = e[i].to; if (dis[v] > dis[u] + e[i].len) { dis[v] = dis[u] + e[i].len; Q.push(make_pair(dis[v], v)); } } } } int main() { int n, m, k; scanf("%d%d%d", &n, &m, &k); for (int i = 1, x, y, z; i <= m; i++) { scanf("%d%d%d", &x, &y, &z); add_e(x, y, z); add_e(y, x, z); for (int j = 1; j <= k; j++) { add_e(x + j * n, y + j * n, z); add_e(y + j * n, x + j * n, z); add_e(x + (j - 1) * n, y + j * n, 0); add_e(y + (j - 1) * n, x + j * n, 0); } } dijkstra(1); int ans = dis[n]; for (int i = 1; i <= k; i++) { ans = min(ans, dis[i * n + n]); } printf("%d", ans); }
标签:head,int,Trails,Revamping,tot,USACO09FEB,vis,len,dis 来源: https://www.cnblogs.com/Chasing-Dreams-Z/p/14615139.html