• 洛谷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

    今天真的是毫无状态啊,各种敲错变量看错题意,这么一道水题WA了六七次……

    先DFS搜出每一个危险城市,再跑spfa就行。需要long long

    之前还写了一个BFS版本的,WA掉就换了DFS(后来发现错因不在BFS)

    BFS代码一并附在下面,那份代码没有加被感染城市不能走的判定,也没有用long long,当然WA咯,不过大致算法还是明确的。

     1 /**/
     2 #include<iostream>
     3 #include<cstdio>
     4 #include<cmath>
     5 #include<cstring>
     6 #include<algorithm>
     7 using namespace std;
     8 const long long inf=1000000000ll*1000000000ll+10ll;
     9 const int mxn=500000;
    10 struct edge{
    11     int v,nxt;
    12 }e[mxn];
    13 int hd[mxn],cnt=0;
    14 void add_edge(int u,int v){
    15     e[++cnt].v=v;e[cnt].nxt=hd[u];hd[u]=cnt;
    16     return;
    17 }
    18 int n,m,k,s;
    19 long long P,Q;
    20 int kp[mxn];//被感染城市 
    21 bool da[mxn];//危险标记
    22 int head=0,tl=0;
    23 int q[mxn];
    24 long long dis[mxn];
    25 bool vis[mxn];
    26 bool ban[mxn];
    27 void dfs(int u)
    28 {
    29     if(dis[u]<=s)da[u]=1;
    30     if(dis[u]==s)return;
    31     for(int i=hd[u];i;i=e[i].nxt){
    32         int v=e[i].v;if(ban[v])continue;
    33         if(dis[v]>dis[u]+1){
    34             dis[v]=dis[u]+1;
    35             dfs(v);
    36         }
    37     }
    38     return;
    39 }
    40 
    41 bool inq[mxn];
    42 void SPFA(int x){
    43     for(int i=1;i<=n;i++)dis[i]=inf;
    44     head=1;tl=1;
    45     q[head]=x;
    46     dis[x]=0;
    47     inq[x]=1;
    48     while(head!=tl+1){
    49         int u=q[head];head=(head+1)%150000;
    50         for(int i=hd[u];i;i=e[i].nxt){
    51             int v=e[i].v;long long cst=(da[v])?Q:P;
    52             if(ban[v])continue;
    53             if(dis[v]>dis[u]+cst){
    54                 dis[v]=dis[u]+cst;
    55                 if(!inq[v]){
    56                     tl=(tl+1)%150000;
    57                     q[tl]=v;
    58                 }
    59             }
    60         }
    61         inq[u]=0;
    62     }
    63     return;
    64 }
    65 int main(){
    66     scanf("%d%d%d%d",&n,&m,&k,&s);
    67     int i,j;
    68     scanf("%lld%lld",&P,&Q);
    69     int u,v;
    70     for(i=1;i<=k;i++){
    71         scanf("%d",&kp[i]);
    72         ban[kp[i]]=1;
    73     }
    74     for(i=1;i<=m;i++){
    75         scanf("%d%d",&u,&v);
    76         add_edge(u,v);
    77         add_edge(v,u);
    78     }
    79     for(int i=1;i<=n;i++)dis[i]=inf;
    80     for(i=1;i<=k;i++){
    81         dis[kp[i]]=0;
    82         dfs(kp[i]);
    83     }
    84     SPFA(1);
    85     if(da[n])dis[n]-=Q;
    86     else dis[n]-=P;
    87     printf("%lld
    ",dis[n]);
    88     return 0;
    89 }
     1 /**/
     2 #include<iostream>
     3 #include<cstdio>
     4 #include<cmath>
     5 #include<cstring>
     6 #include<algorithm>
     7 using namespace std;
     8 const int mxn=500000;
     9 struct edge{
    10     int v,nxt;
    11 }e[mxn];
    12 int hd[mxn],cnt=0;
    13 void add_edge(int u,int v){
    14     e[++cnt].v=v;e[cnt].nxt=hd[u];hd[u]=cnt;
    15     return;
    16 }
    17 int n,m,k,s;
    18 int P,Q;
    19 int kp[mxn];//被感染城市 
    20 bool da[mxn];//危险标记
    21 int head=0,tl=0;
    22 int q[mxn];
    23 int dis[mxn];
    24 bool vis[mxn];
    25 void BFS(int x){
    26     memset(vis,0,sizeof vis);
    27     int i,j;
    28     head=1;    tl=1;
    29     q[tl]=x;vis[x]=1;da[x]=1;
    30     dis[x]=0;
    31     int u,v;
    32     while(head!=tl+1){
    33         u=q[head];head=(head+1)%150000;
    34         for(i=hd[u];i;i=e[i].nxt){
    35             v=e[i].v;
    36             if(!vis[v]){
    37                 dis[v]=dis[u]+1;
    38                 if(dis[v]<s){
    39                     tl=(tl+1)%150000;
    40                     q[tl]=v;
    41                 }
    42                 da[v]=1;
    43                 vis[v]=1;
    44             }
    45         }
    46     }
    47     return;
    48 }
    49 bool inq[mxn];
    50 void SPFA(int x){
    51     memset(dis,0x3f,sizeof dis);
    52     head=1;tl=1;
    53     q[head]=x;
    54     dis[x]=0;
    55     inq[x]=1;
    56     while(head!=tl+1){
    57         int u=q[head];head=(head+1)%150000;
    58         for(int i=hd[u];i;i=e[i].nxt){
    59             int v=e[i].v;int cst=(da[v])?Q:P;
    60             if(dis[v]>dis[u]+cst){
    61                 dis[v]=dis[u]+cst;
    62                 if(!inq[v]){
    63                     tl=(tl+1)%150000;
    64                     q[tl]=v;
    65                 }
    66             }
    67         }
    68         inq[u]=0;
    69     }
    70     return;
    71 }
    72 int main(){
    73     scanf("%d%d%d%d",&n,&m,&k,&s);
    74     int i,j;
    75     scanf("%d%d",&P,&Q);
    76     int u,v;
    77     for(i=1;i<=k;i++){
    78         scanf("%d",&kp[i]);
    79     }
    80     for(i=1;i<=m;i++){
    81         scanf("%d%d",&u,&v);
    82         add_edge(u,v);
    83         add_edge(v,u);
    84     }
    85     for(i=1;i<=k;i++){
    86         BFS(kp[i]);
    87     }
    88     SPFA(1);
    89     if(da[n])dis[n]-=Q;
    90     else dis[n]-=P;
    91     printf("%d
    ",dis[n]);
    92     return 0;
    93 }
    BFS
  • 相关阅读:
    沟通的5个步骤
    安家博客园,发表感想
    postman 简单教程-实现简单的接口测试
    Postman的基本使用
    面试题-如何测试一个APP
    Fiddler快捷方式导出jmeter脚本,傻瓜式
    Servlet学习(三)
    scala学习(一)
    白底抠图
    Servlet学习(二)
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/5906924.html
Copyright © 2020-2023  润新知