洛谷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\n",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\n",dis[n]);
92     return 0;
93 }

BFS

时间: 2024-10-17 16:32:29

洛谷P3393 逃离僵尸岛的相关文章

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

题目描述 小a住的国家被僵尸侵略了!小a打算逃离到该国唯一的国际空港逃出这个国家. 该国有N个城市,城市之间有道路相连.一共有M条双向道路.保证没有自环和重边. K个城市已经被僵尸控制了,如果贸然闯入就会被感染TAT...所以不能进入.由其中任意城市经过不超过S条道路就可以到达的别的城市,就是危险城市.换句话说只要某个没有被占城市到某个被占城市不超过s距离,就是危险. 小a住在1号城市,国际空港在N号城市,这两座城市没有被侵略.小a走每一段道路(从一个城市直接到达另外一个城市)得花一整个白天,所

P3393 逃离僵尸岛

题目描述 小a住的国家被僵尸侵略了!小a打算逃离到该国唯一的国际空港逃出这个国家. 该国有N个城市,城市之间有道路相连.一共有M条双向道路.保证没有自环和重边. K个城市已经被僵尸控制了,如果贸然闯入就会被感染TAT...所以不能进入.由其中任意城市经过不超过S条道路就可以到达的别的城市,就是危险城市.换句话说只要某个没有被占城市到某个被占城市不超过s距离,就是危险. 小a住在1号城市,国际空港在N号城市,这两座城市没有被侵略.小a走每一段道路(从一个城市直接到达另外一个城市)得花一整个白天,所

Luogu P3393 逃离僵尸岛【最短路】By cellur925

题目传送门 题目大意:(其实概括出来也就基本做完了hh)在一张有$n$个点,$m$条边的无向图上,有$k$个点是不能经过的,而与之距离不超过$s$的点,到他们会花费$Q$元,到其他点会花费$p$元,求1到$n$花费的最小价钱. 概括完题意也就非常明了了.我们需要把图上的点分为三类,这部分可以由一个$bfs$求得. void bfs() { while(!q1.empty()) { int u=q1.front().second; int val=q1.front().first;q1.pop()

AC日记——逃离僵尸岛 洛谷 P3393

逃离僵尸岛 思路: spfa: 代码: #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define maxn 200005 #define maxque 1800056 #define INF 1e12 #define ll long long ll n,m,E[maxque],V[maxque],cnt,

题解 P3393 【逃离僵尸岛】

题解 P3393 [逃离僵尸岛] 题目链接 没错这题就是单元最短路径的裸题. 同时也可以练习一下多源BFS 在处理被占领点周围的"危险点"时我们可以使用bfs,对于k个被占领点一个一个BFS显然太慢没有B格了,所以我们可以多源BFS,也就是第一次就把所有的被占领点压到队列里. 染完色以后处理每个点的权值,危险点的权值设为q,安全点的权值设为p,被占领的点权值设为一个比较大的数. 然后从点1跑最短路径就行了. 总之这是一道有点细节的模板题,要开long long不然玄学错误 代码: /*

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

题解--逃离僵尸岛(BFS+最短路+虚拟节点) 一道很巧妙的最短路问题,细节也要注意 题面 Description 小a住的国家被僵尸侵略了!小a打算逃离到该国唯一的国际空港逃出这个国家. 该国有N个城市,城市之间有道路相连.一共有M条双向道路.保证没有自环和重边. K个城市已经被僵尸控制了,如果贸然闯入就会被感染TAT...所以不能进入.由其中任意城市经过不超过S条道路就可以到达的别的城市,就是危险城市.换句话说只要某个没有被占城市到某个被占城市不超过s距离,就是危险. 小a住在1号城市,国际

逃离僵尸岛

[题目描述] 现有N个城市,城市之间有道路相连,一共有M条双向道路,保证没有自环和重边. 现有K个城市已经被僵尸控制,所以不能进入.若某个正常城市到某个僵尸城市的距离不超过S,则称此城市为危险城市. 小A住在1号城市,他想去N号城市避难,这两座城市没有被侵略.白天小A会走一段道路,晚上要住在所处城市.在正常城市需花费P元,而在危险城市,由于安保措施,所以会变贵,为Q元.所有危险城市的住宿花费相同,正常城市也是如此.且在1号城市和N号城市,小A不需要住店. 现询问从1号城市到N号城市所需要的最小花

洛谷 2691逃离

传送门: https://www.luogu.org/problem/show?pid=2691 裸的最大流 每个点拆成两个点 流量设置成1 表示只能跑一遍 然后边界向汇点连边跑dinic 最终流量如果大于等于m就是逃离 #include<algorithm> #include<iostream> #include<cstring> #include<cstdio> #include<queue> #include<cmath> us

洛谷 P2691 逃离

题目描述 一个n×n栅格是由n行和n列顶点组成的一个无向图,如图所示.用(i,j)表示处于第i行第j列的顶点.除了边界顶点(即满足i=1,i=n,j=1或j=n的顶点(i,j)),栅格中的所有其他顶点都有四个相邻的顶点. 给定栅格中的m≤n2个起始点(x1,y1),…, (xm,ym),逃脱问题即确定从起始顶点到边界上的任何m个相异的顶点之间,是否存在m条顶点不相交的路径.例如,图中左边的栅格包含了一个逃脱,黑点表示起始点,一个逃脱路径由灰线表示:而右边的栅格则没有逃脱. 现给定一个栅格的n和m