题解 P3393 逃离僵尸岛
Posted yuanqiqhfz
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了题解 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
以上是关于题解 P3393 逃离僵尸岛的主要内容,如果未能解决你的问题,请参考以下文章