「BJWC 2012」冻结「分层图+最短路」

版权声明:本文为hzy原创文章,未经博主允许不可随意转载。 https://blog.csdn.net/Binary_Heap/article/details/82828775

题目传送门

题解

分层图是一种不错的技巧。对于这题来说,把图复制成 k + 1 k+1 份,分别命名为 0 , 1 , . . . , k 0,1,...,k 层。第 i i 层的含义就是已经用了 i i 次加速魔法。

读入一条边,每层连双向边,层与层之间,底层往上层连权值减半的单向边,单向意味着只能上不能下。

然后答案就是跑最短路然后取 k + 1 k+1 层的 d i s ( n ) dis(n) 最小值.

#include <cstdio>
#include <vector>
#include <queue>
using namespace std;

#define P pair<int, int>
#define px first
#define py second

const int N = 5010;

int n, m, k;
int dis[N];
vector<P> G[N];

int Dijkstra() {
	priority_queue<P, vector<P>, greater<P> > Q;
	Q.push(P(dis[1] = 0, 1));
	for(int i = 2; i <= 5000; i ++) dis[i] = 1 << 29;
	for(; Q.size(); ) {
		P k = Q.top(); Q.pop(); int u = k.py;
		if(dis[u] < k.px) continue ;
		for(int i = 0; i < G[u].size(); i ++) {
			int v = G[u][i].px, w = G[u][i].py;
			if(dis[v] > dis[u] + w) {
				Q.push(P(dis[v] = dis[u] + w, v));
			}
		}
	}
	int ans = dis[n], base = n;
	for(int i = 1; i <= k; i ++, base += n)
		if(ans > dis[base + n]) ans = dis[base + n];
	return ans;
}

int main() {
	scanf("%d%d%d", &n, &m, &k);
	for(int i = 1, u, v, w; i <= m; i ++) {
		scanf("%d%d%d", &u, &v, &w);
		int base = 0;
		for(int j = 1; j <= k + 1; j ++, base += n) {
			G[base + u].push_back(P(base + v, w));
			G[base + v].push_back(P(base + u, w));
			if(base) {
				G[base - n + u].push_back(P(base + v, w >> 1));
				G[base - n + v].push_back(P(base + u, w >> 1));
			}
		}
	}
	
	printf("%d\n", Dijkstra());
	return 0;
}

猜你喜欢

转载自blog.csdn.net/Binary_Heap/article/details/82828775
今日推荐