[洛谷P4568][JLOI2011]飞行路线

题目大意:最短路,可以有$k$条边无费用

题解:分层图最短路,建成$k$层,层与层之间的边费用为$0$

卡点:空间计算出错,建边写错

 

C++ Code:

#include <cstdio>
#include <queue>
#define __N__ 10010
#define __K__ 11
#define __M__ 50010
#define maxn (__N__ * __K__)
#define maxm (__M__ * __K__ << 1)
int head[maxn], cnt;
struct Edge {
	int to, nxt, w;
} e[maxm << 1];
inline void add(int a, int b, int c) {
	e[++cnt] = (Edge) {b, head[a], c}; head[a] = cnt;
}
inline void addE(int a, int b, int c) {
	add(a, b, c);
	add(b, a, c);
}

int n, m, k, S, T;
int d[maxn];
bool vis[maxn];
struct Dis {
	int pos, d;
	inline Dis() {}
	inline Dis(int __pos, int __d) {pos = __pos, d = __d;}
	inline friend bool operator < (const Dis &lhs, const Dis &rhs) {
		return lhs.d > rhs.d;
	}
};
std::priority_queue<Dis> q;
void dijkstra() {
	__builtin_memset(d, 0x3f, sizeof d);
	q.push(Dis(S, d[S] = 0));
	while (!q.empty()) {
		int u = q.top().pos; q.pop();
		if (u == T) return ;
		if (vis[u]) continue;
		vis[u] = true;
		for (int i = head[u]; i; i = e[i].nxt) {
			int v = e[i].to;
			if (d[v] > d[u] + e[i].w) {
				d[v] = d[u] + e[i].w;
				q.push(Dis(v, d[v]));
			}
		}
	}
}

int main() {
	scanf("%d%d%d%d%d", &n, &m, &k, &S, &T);
	for (int i = 0, a, b, c; i < m; i++) {
		scanf("%d%d%d", &a, &b, &c);
		for (int j = 0; j <= k; j++) addE(n * j + a, n * j + b, c);
		for (int j = 0; j < k; j++) add(n * j + a, n * (j + 1) + b, 0), add(n * j + b, n * (j + 1) + a, 0);
	}
	T += n * k;
	dijkstra();
	printf("%d\n", d[T]);
	return 0;
}

  

posted @ 2018-11-08 20:21  Memory_of_winter  阅读(163)  评论(0编辑  收藏  举报