kkk 口中的模板题,当我一直在wa的时候一直在想这题怎么会是模板题???但做完发现确实是模板题,,,

这道题,告诉了我这种只会模板的蒟蒻求最短路时,bfs在所需要的节点比较少时(距离比较短时)或许是个很好的选择。

首先,先说下自己的思路,我一开始想的是对每一个感染城市跑spfa找危险城市,最后再跑一遍对全图的spfa,然而只有28分,t两个点(6,7),wa了三个点(2,3,4);

28分代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
inline int read(){int x = 0;int f = 1;char c = getchar();while(c<'0'||c>'9'){if(c == '-')f = -f;c = getchar();}while(c<='9'&&c>='0'){x = x*10 + c - '0';c = getchar();} return x*f;
}
const int maxn = 2002000;
const int inf = 2147483647;
int cnt,p,q,n,m,k,s;
int x[maxn],y[maxn],val[maxn],vis[maxn],c[maxn],head[maxn*2];
long long dis[maxn];
struct edge{int from,to,v;
}e[maxn];
void add(int a,int b,int c){cnt++;e[cnt].from = head[a];e[cnt].to = b;e[cnt].v = c;head[a] = cnt;
}
void spfa(int start){for(int i = 1; i<=n; i++)dis[i] = inf;memset(vis,0,sizeof(vis));queue<int>que;que.push(start);dis[start] = 0;vis[start] = 1;while(!que.empty()){int f = que.front();que.pop();vis[f] = 0;for(int i = head[f] ; i ;i = e[i].from){int u = e[i].to;if(dis[u] > dis[f] + e[i].v){dis[u] = dis[f] + e[i].v;if(!vis[u]){vis[u] = 1;que.push(u);}}}}
}
int main(){n = read();m = read();k = read();s = read();p = read();q = read();for(int i = 1; i<=k; i++)c[i] = read();for(int i = 1; i<=m; i++){int a,b;x[i] = read(); y[i] = read();add(x[i],y[i],1);add(y[i],x[i],1);}for(int i = 1; i<=n; i++)val[i] = p;for(int i = 1; i<=k; i++){spfa(c[i]);for(int i = 1; i<=n; i ++){if(dis[i] <= s)val[i] = q;} }// for(int i = 1; i<=n; i++)cout<<dis[i]<<' '; val[1] = 0;val[n] = 0;memset(e,0,sizeof(e));memset(head,0,sizeof(head));for(int i = 1; i<=m; i++){add(x[i],y[i],val[y[i]]);add(y[i],x[i],val[x[i]]);}//cout<<dis[n]<<' ';spfa(1);printf("%lld",dis[n]);return 0;
}

其实很容易就发现对于全图的spfa是很浪费的当距离超过s完全就可以停止,所以我们基于spfa的思想对所有僵尸控制的城市进行bfs对在s距离内的城市进行标记,bfs结束后,对边权进行赋值,一条边的权值为这条边所指向城市的旅店所需花费,(所以这里需要注意当指向城市为n时需要跳过),最后一遍最短路即可求出所需花费,但在这里需要注意两点!!!

1 :开long long

2:dis 最大值因为会爆int的缘故所以不能用2147483647!!!

贴代码

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<queue>
#include<cstring>
#define inf 31147483647//因为会爆int所以所求的值会超过214748367,所以一定要比2147483647大
#define ll long long
using namespace std;
inline int read(){int x = 0;int f = 1;char c = getchar();while(c<'0'||c>'9'){if(c=='-')f=-f;c=getchar();}while(c<='9'&&c>='0'){x=x*10+c-'0';c=getchar();}return x*f;
}
const int maxn = 5000000;
int cnt,n,m,k,ans,s,p,q;
queue<int>que;
struct edge{int from,to,v;
}e[maxn];
ll dis[maxn];
int head[maxn],vis[maxn],flag[maxn];
void add(int a,int b){cnt++;e[cnt].from = head[a];e[cnt].to = b;head[a] = cnt;
}
void spfa(){memset(vis,0,sizeof(vis));for(int i = 1; i<=n; i++)dis[i] = inf;que.push(1);dis[1] = 0;vis[1] = 1;while(!que.empty()){int f = que.front();que.pop();vis[f] = 0;for(int i = head[f] ; i ; i =e[i].from){int u = e[i].to;if(dis[u] > dis[f] + e[i].v){dis[u] = dis[f] + e[i].v;if(!vis[u]){vis[u] = 1;que.push(u);}}} }
}
int main(){n = read(); m = read(); k = read(); s = read(); p = read(); q = read();for(int i = 1; i<=k; i++){int a;a = read();flag[a]++;//标记僵尸控制的城市que.push(a);}for(int i = 1; i<=m; i++){int a,b;a = read();b = read();add(a,b);add(b,a);} //bfs求危险城市while(!que.empty()){int f = que.front();que.pop();if(dis[f] == s)continue;for(int i = head[f] ; i ; i = e[i].from){if(dis[e[i].to] == 0){dis[e[i].to] = dis[f] + 1;que.push(e[i].to);  }}}  //对边权赋值for(int i = 1; i<=cnt; i++){if(e[i].to == n)continue;//终点不包括在内的原因所以跳过//如果是被僵尸控制的城市把边权赋值成一个极大值保证这条边不会出现在最后所求的路径里if(flag[e[i].to]){e[i].v = inf;continue;}//如果是危险城市赋值成q否则复制成pif(dis[e[i].to])e[i].v =q;else e[i].v = p;}spfa();printf("%lld",dis[n]);  return 0;
}

完结

转载于:https://www.cnblogs.com/Euplectella/p/9907248.html

P3393 逃离僵尸岛相关推荐

  1. luogu P3393 逃离僵尸岛(点权最短路 + 多源BFS)

    P3393 逃离僵尸岛 最短路,有点的不能到达我们就直接把他的权值赋值为INF即可. bfs预处理一下每个点的危险程度. 因为这里没有边权是点权,我们可以把边权转化为两端点的权值和,或者直接跑点权最短 ...

  2. 洛谷 P3393 逃离僵尸岛 ( spfa+dfs) 题解

    题目来源: https://www.luogu.org/problemnew/show/P3393 题目描述: 题目描述 小a住的国家被僵尸侵略了!小a打算逃离到该国唯一的国际空港逃出这个国家. 该国 ...

  3. P3393 逃离僵尸岛 最短路dijkstra

    题目描述 小a住的国家被僵尸侵略了!小a打算逃离到该国唯一的国际空港逃出这个国家. 该国有N个城市,城市之间有道路相连.一共有M条双向道路.保证没有自环和重边. K个城市已经被僵尸控制了,如果贸然闯入 ...

  4. 洛谷P3393 逃离僵尸岛

    题目描述 小a住的国家被僵尸侵略了!小a打算逃离到该国唯一的国际空港逃出这个国家. 该国有N个城市,城市之间有道路相连.一共有M条双向道路.保证没有自环和重边. K个城市已经被僵尸控制了,如果贸然闯入 ...

  5. 【luogu P3393 逃离僵尸岛】 题解

    题目链接:https://www.luogu.org/problemnew/show/P3393 被占领的点可以先连在一个点上然后只需要对这一个点bfs一遍就可以求所有的危险点 #include &l ...

  6. [洛谷P3393]逃离僵尸岛

    题目大意:有n个城市m条双向道路,还有k个已经被僵尸占领的城市,规定:被占领城市不能经过,走不超过s条道路就能到达被占领城市的算危险城市,路费Q,其他城市算安全城市,路费P.求从1走到n的最少花费(1 ...

  7. 洛谷 P3393 逃离僵尸岛

    题目大意: 传送门 解题思路: 将所有被控制的点视为点000,将所有与被控制的点连边的点连向000,暂定所有边权为111 然后以000为起点跑一遍dijdijdij,如果dis[i]≤sdis[i]\ ...

  8. luogu P3393 逃离僵尸岛

    analysis 关键是解决这个问题: 给你几个点,其他的点离这些给出的点的最近距离是多少 这个很简单: 我们可以自己给出一个点,然后向每个被标记的点连一条单向边,这样就只需要进行一次 dijkstr ...

  9. 洛谷P3393逃离僵尸岛

    猛地一看,这是啥啊???? 思索了一下下,发现,嗯,这是一张最短路,我们不需要记录边权,只需要在更新到这个点时,加上点权就好 然后如何处理危险城市呢?用dfs遍历并记录深度,然后更改点权 最后两点比较 ...

最新文章

  1. web服务器(IIS)的操作步骤
  2. as3绘制抛物线(二)
  3. docker 容器退出自动删除 一次性运行
  4. C++ 11三个新特性的简单使用 - std::function、lambda 表达式、智能指针
  5. 程序员面试题精选100题(51)-顺时针打印矩阵[算法]
  6. 中国电线电缆行业发展形势与投资规模预测报告2022版
  7. ArcGIS中国工具(ArcGISCTools)3.2 安装教程(附安装包下载)
  8. opencv3.4.1 + vs 2017 + cmake 3.11.3 + win10 配置. 终章
  9. 防止ViewPager中的Fragment被销毁的方法
  10. R语言机器学习:xgboost的使用及其模型解释
  11. X-Scan介绍和使用方法
  12. 隐藏IP地址的三种方法
  13. 【无标题】win7系统怎么配置adb环境变量
  14. python知识点总结2
  15. 智能名片小程序开发文档概要
  16. win10蓝牙已配对连接不上_win10蓝牙耳机显示已配对但没有声音的具体处理方法...
  17. 学习计算机英语总结,英语学习方法总结
  18. 解决ios7.x越狱后静态壁纸变为空白
  19. 三维几何 --- 计算几何模板
  20. 珠宝达人必须知晓的10大宝石产地

热门文章

  1. 防火墙设置入站规则和ping请求超时解决办法(Tomcat+Windows项目部署后续)
  2. 【c++教程】2.10-复数类型
  3. 深圳哪里的海景比较美 深圳看海点推荐
  4. 与多家大厂的“爱恨纠葛”,兜兜转转他最后还是投入了腾讯的怀抱
  5. 多目标优化算法:基于非支配排序的人工兔优化算法(Non-Dominated Sorting Artificial Rabbits Optimization ,NSARO)
  6. CS CK VT系列贴片型铝电解电容器特点
  7. python打靶问题,递归算法
  8. 3dmax说课稿计算机平面设计,3DMAX说课稿.doc
  9. 7-39 魔法优惠券
  10. 我要把我的学生培养成“狼”