题解【逃离僵尸岛】(洛谷P3393)

题意

\(n\)个点\(m\)条边。现有一些点被感染,其余的点中与被感染的点距离\(\leq S\) 的点是危险的点,点权为\(Q\);与所有被感染的点距离\(>S\)的点为安全的点,点权为\(P\)\(1\)号店与\(n\)号点点权始终为\(0\),求\(1\)号点走到\(n\)号点的最小全值(被感染的点不能走)。

分析一下

  • 最短路板子题吖~ (调了一上午)
  • 首先通过\(bfs\)将所有的危险点求出来,并把点赋上权值。
  • 然后跑最短路就好了。
  • 点权怎么跑最短路?
  • 将边权当做连接的两个点的点权之和,输出答案时除以二就好了。

代码君

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
#define int long long

using namespace std;

const int inf = 1e9 + 7;
const int MAXN = 100005;
int n, m, K, S, P, Q;
int val[MAXN], dis[MAXN];
int dan[MAXN], dep[MAXN], vis[MAXN], zomb[MAXN];
int edgenum, front[MAXN], vet[MAXN << 2], nxt[MAXN << 2];
queue<int> que;

inline void addedge(int u, int v) {
	nxt[++edgenum] = front[u];
	front[u] = edgenum;
	vet[edgenum] = v;
}

void bfs() {
	for (int i = 1; i <= K; i++) {
		dan[zomb[i]] = 1;
		dep[zomb[i]] = 0;
		que.push(zomb[i]);
	}
	while (!que.empty()) {
		int u = que.front(); que.pop();
		if (dep[u] == S)
			continue;
		for (int e = front[u]; e; e = nxt[e]) {
			int v = vet[e];
			if (dan[v])
				continue;
			dan[v] = 1;
			dep[v] = dep[u] + 1;
			que.push(v);
		}
	}
} //bfs求出所有危险点。 

void SPFA() {
	for (int i = 1; i <= n; i++)
		dis[i] = inf * 9999, vis[i] = 0;
	dis[1] = 0, vis[1] = 1;
	que.push(1);
	while (!que.empty()) {
		int u = que.front(); que.pop();
		vis[u] = 0;
		for (int e = front[u]; e; e = nxt[e]) {
			int v = vet[e];
			if (dis[v] > dis[u] + val[u] + val[v]) { //将边权当做两个点权之和。 
				dis[v] = dis[u] + val[u] + val[v];
				if (!vis[v]) {
					vis[v] = 1;
					que.push(v);
				}
			}
		}
	}
} //最短路 

signed main() {
	scanf("%lld%lld%lld%lld%lld%lld", &n, &m, &K, &S, &P, &Q);
	for (int i = 1; i <= K; i++)
		scanf("%lld", &zomb[i]);
	for (int i = 1; i <= m; i++) {
		int x, y;
		scanf("%lld%lld", &x, &y);
		addedge(x, y), addedge(y, x);
	}
	bfs();
	for (int i = 1; i <= n; i++)
		if (dan[i])
			val[i] = Q;
		else val[i] = P; //赋点权 
	for (int i = 1; i <= K; i++)
		val[zomb[i]] = inf; //这样就能在跑最短路时不取被感染的点 
	val[1] = val[n] = 0;
	SPFA();
	printf("%lld\n", dis[n] / 2);
	return 0;
}
posted @ 2018-08-13 20:02  JackHomes  阅读(344)  评论(0编辑  收藏  举报