[单源最短路]逃离僵尸岛

(捂脸)随便点了道题写 突然发现是道水题 立马AAAA掉了

题目描述

小a住的国家被僵尸侵略了!小a打算逃离到该国唯一的国际空港逃出这个国家。

该国有N个城市,城市之间有道路相连。一共有M条双向道路。保证没有自环和重边。

K个城市已经被僵尸控制了,如果贸然闯入就会被感染TAT...所以不能进入。由其中任意城市经过不超过S条道路就可以到达的别的城市,就是危险城市。换句话说只要某个没有被占城市到某个被占城市不超过s距离,就是危险。

小a住在1号城市,国际空港在N号城市,这两座城市没有被侵略。小a走每一段道路(从一个城市直接到达另外一个城市)得花一整个白天,所以晚上要住旅店。安全的的城市旅馆比较便宜要P元,而被危险的城市,旅馆要进行安保措施,所以会变贵,为Q元。所有危险的城市的住宿价格一样,安全的城市也是。在1号城市和N城市,不需要住店。

小a比较抠门,所以他希望知道从1号城市到N号城市所需要的最小花费。

输入数据保证存在路径,可以成功逃离。输入数据保证他可以逃离成功。

输入格式:

第一行4个整数(N,M,K,S)

第二行2个整数(P,Q)

接下来K行,ci,表示僵尸侵占的城市

接下来M行,ai,bi,表示一条无向边

输出格式:

一个整数表示最低花费

输入样例#1:

13 21 1 1
1000 6000
7
1 2
3 7
2 4
5 8
8 9
2 5
3 4
4 7
9 10
10 11
5 9
7 12
3 6
4 5
1 3
11 12
6 7
8 11
6 13
7 8
12 13

输出样例#1:

11000

代码

用bfs跑一遍 把危险地带标记出来 然后跑一遍spfa就过了 注意 被僵尸占领的城市是不能走的(qwqq不然会被吃掉脑子)

//#define fre yes

#include <queue>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;

const int maxn = 400005;
long long cur[maxn];
int date[maxn];
bool Use[maxn];
int arr[maxn];

int head[maxn];
int ver[maxn];
int to[maxn];

long long d[maxn];
int inq[maxn];

int n,m,k,s,tot;
int P,Q;

template<typename T>inline void read(T&x)
{
    x = 0;char c;int lenp = 1;
    do { c = getchar();if(c == '-') lenp = -1; } while(!isdigit(c));
    do { x = x * 10 + c - '0';c = getchar(); } while(isdigit(c));
    x *= lenp;
}

void bfs()
{
    memset(date,0,sizeof(date));

    queue<int> q;
    for (int i=1;i<=k;i++)
    {
        q.push(arr[i]);
        Use[arr[i]] = 1;
        date[arr[i]] = 0;
    }
    
    while(!q.empty())
    {
        int now = q.front();q.pop();
        if(date[now] == s) continue;
        for (int i=head[now];~i;i=to[i])
        {
            int v = ver[i];
            if(!Use[v]) 
            { 
                Use[v] = 1;
                q.push(v);
                date[v] = date[now] + 1; 
            }
        }
    }
}

void addedge(int x,int y)
{
    ver[tot] = y;
    to[tot] = head[x];
    head[x] = tot++;
}

void spfa(int x)
{
    queue<int> q;
    
    q.push(x);
    inq[x] = 1;d[x] = 0;
    while(!q.empty())
    {
        int now = q.front();q.pop();inq[now] = 0;
        for (int i=head[now];~i;i=to[i])
        {
            int v = ver[i];
            if(d[v] > d[now] + cur[v] + cur[now])
            {
                d[v] = d[now] + cur[v] + cur[now];
                if(inq[v]) continue;
                inq[v] = 1;
                q.push(v);
            }
        }
    }
}

int main()
{
    memset(head,-1,sizeof(head));
    memset(d,0x3f,sizeof(d));

    read(n);read(m);read(k);read(s);
    read(P);read(Q);

    for (int i=1;i<=k;i++)
    {
        int x;
        read(x);
        arr[i] = x;
    }

    for (int i=1;i<=m;i++)
    {
        int x,y;
        read(x);read(y);
        addedge(x,y);
        addedge(y,x);
    }

    bfs();
    for (int i=1;i<=n;i++)
    {
        if(Use[i] == 1) cur[i] = Q;
        else cur[i] = P;
    }

    for (int i=1;i<=k;i++) cur[arr[i]] = 10000000; 

    cur[1] = cur[n] = 0;
    spfa(1);
    printf("%lld
",d[n]/2);
    return 0;
}
原文地址:https://www.cnblogs.com/Steinway/p/9242801.html