题解 P3393 【逃离僵尸岛】
作者:互联网
题解 P3393 【逃离僵尸岛】
没错这题就是单元最短路径的裸题。
同时也可以练习一下多源BFS
在处理被占领点周围的“危险点”时我们可以使用bfs,对于k个被占领点一个一个BFS显然太慢没有B格了,所以我们可以多源BFS,也就是第一次就把所有的被占领点压到队列里。
染完色以后处理每个点的权值,危险点的权值设为q,安全点的权值设为p,被占领的点权值设为一个比较大的数。
然后从点1跑最短路径就行了。
总之这是一道有点细节的模板题,要开long long不然玄学错误
代码:
/*PROPERTY OF YUANQI*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <stack>
#define ll long long
#define N 200005
using namespace std;
inline ll read()
{
ll x = 0, f = 1;
char c = getchar();
while (c < '0' || c > '9') {
if (c == '-') f = -1;
c = getchar();
}
while (c >= '0' && c <= '9') {
x = x * 10 + c - '0';
c = getchar();
}
return x * f;
}
ll n, m, tot, head[N], P, Q, K, S, c[N], cost[N], dis[N], vis[N];
queue < int > q;
struct edge {
ll to, next;
edge () {
}
edge (int x, int y) {
to = x, next = y;
}
}a[2 * N];
void addedge(ll from, ll to) {
a[++tot] = edge(to, head[from]);
head[from] = tot;
}
void spfa() { //他死了
while (!q.empty()) {
int u = q.front();
q.pop();
vis[u] = false;
for (int i = head[u]; i; i = a[i].next) {
ll v = a[i].to;
if (dis[u] + cost[v] < dis[v]) {
dis[v] = dis[u] + cost[v];
if (!vis[v]) {
q.push(v);
vis[v] = true;
}
}
}
}
}
int main()
{
memset(dis, 0x3f3f3f3f, sizeof(dis));
n = read(), m = read(), K = read(), S = read();
P = read(), Q = read();
for (int i = 1; i <= K; i++) {
int ci = read();
c[ci] = S + 1;
q.push(ci);
}
for (int i = 1; i <= m; i++) {
int a1 = read(), a2 = read();
addedge(a1, a2);
addedge(a2, a1);
}
while (!q.empty()) {
int u = q.front();
q.pop();
if (c[u] == 1) continue;
for (int i = head[u]; i; i = a[i].next) {
int v = a[i].to;
if (!c[v]) {
c[v] = c[u] - 1;
q.push(v);
}
}
}//多源bfs c数组表示这个点是否还能扩展
for (int i = 1; i <= n; i++) {
if (c[i] == S + 1) cost[i] = 1000000;
else if (c[i]) cost[i] = Q;
else cost[i] = P;
}//初始化点权
cost[1] = 0, cost[n] = 0;
dis[1] = 0;
q.push(1);
vis[1] = true;
spfa();//他死了
cout << dis[n] << endl;
return 0;
}
ps:最好学习一下迪杰斯特拉不然很可能被卡掉qwq
19.09.22
标签:read,题解,ll,逃离,int,P3393,权值,include,dis 来源: https://www.cnblogs.com/YuanqiQHFZ/p/11622322.html