zoukankan      html  css  js  c++  java
  • 洛谷 P3393 逃离僵尸岛

    题目描述

    小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

    说明

    对于20%数据,N<=50

    对于100%数据,2 ≦ N ≦ 100000, 1 ≦ M ≦ 200000, 0 ≦ K ≦ N - 2, 0 ≦ S ≦ 100000

    1 ≦ P < Q ≦ 100000

    思路:题目比较简单,但因为细节,挂的比较惨。。。

    一个一个压进栈和全部一起压入,第一种方法可能会漏解。

    /*
    关键在于在尽量短的时间内判断一个城市是
    安全城市还是被危险城市。
    最后跑一个最短路。
    数组边开两倍。 
    
    首先 开long long  
    */
    #include<queue> 
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define MAXN 100010
    using namespace std;
    int n,m,k,s,p,q,tot;
    int c[MAXN],vis[MAXN];
    long long cost[MAXN],dis[MAXN];
    struct nond{ long long dis;int id; };
    int to[MAXN*4],net[MAXN*4],head[MAXN];
    queue<nond>qu;
    int read(){
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    bool operator < (const nond &a,const nond &b){
        return a.dis>b.dis;
    }
    void add(int u,int v){
        to[++tot]=v;net[tot]=head[u];head[u]=tot;
    }
    void work(){
        while(!qu.empty()){
            nond tmp=qu.front();
            qu.pop();
            if(tmp.dis==s)    continue;
            for(int i=head[tmp.id];i;i=net[i])//wa点 
                if(!vis[to[i]]){
                    vis[to[i]]=1;cost[to[i]]=q;
                    qu.push((nond){tmp.dis+1,to[i]});
                }
        }
    }
    void dijkstra(int be){
        priority_queue<nond>que;
        for(int i=1;i<=n;i++)    dis[i]=21474836476666;//wa点 
        dis[be]=0;que.push((nond){0,be});
        while(!que.empty()){
            nond now=que.top();
            que.pop();
            if(dis[now.id]!=now.dis)    continue;
            for(int i=head[now.id];i;i=net[i])
                if(dis[to[i]]>dis[now.id]+cost[to[i]]){
                    dis[to[i]]=dis[now.id]+cost[to[i]];
                    que.push((nond){dis[to[i]],to[i]});
                }
        }
    }
    int main(){
        n=read();m=read();k=read();s=read();
        p=read();q=read();
        for(int i=1;i<=k;i++){
            c[i]=read();vis[c[i]]=1; 
            cost[c[i]]=21474836476666;//wa点 
            qu.push((nond){0,c[i]});
        }    
        for(int i=1;i<=m;i++){
            int u=read();
            int v=read();
            add(u,v);add(v,u);
        }
        work();
        for(int i=1;i<=n;i++)
            if(!cost[i])    cost[i]=p;
        cost[1]=cost[n]=0;
        dijkstra(1);
        printf("%lld",dis[n]);
    }
  • 相关阅读:
    Linux入门学习(二)
    Linux入门学习(一)
    正则表达式(二)
    正则表达式入门
    我的第一个博客
    Java每日问题汇总-04
    Java每日问题汇总-03
    Java每日问题汇总-02
    #{ }和${ }参数值的获取的区别
    Cause: org.apache.ibatis.binding.BindingException: Parameter 'eName' not found.解决方案
  • 原文地址:https://www.cnblogs.com/cangT-Tlan/p/9878089.html
Copyright © 2011-2022 走看看