题解 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 逃离僵尸岛的主要内容,如果未能解决你的问题,请参考以下文章

P3393 逃离僵尸岛

洛谷P3393 逃离僵尸岛

Luogu P3393 逃离僵尸岛

图论-最短路P3393逃离僵尸岛

洛谷⑨月月赛Round2 P3393逃离僵尸岛[最短路]

题解——逃离僵尸岛(BFS+最短路+虚拟节点)