题意:好长...从(0,0)走到(w-1,h-1),墓碑不能走,走到传送门只能进去不能走到其他地方,经过传送门时间会变化w(可能为负),其他地方都能上下左右走。如果能无限返老还童输出Never,走不到终点输出Impossible,其他输出最短时间。

思路:没想到是最短路,刚看懂题目还以为是暴搜+剪枝,听到无限返老还童是负权回路才想起来可以用最短路spfa来做。这题就是建边跑spfa就行了,建边方法如题意。注意一下建边的时候终点不能为边的起始,这里WA了,因为到终点了就结束了,如果还能走可能会进入负权回路。题目输出的优先级应该是这样的:有never先输出,其次最短路,最后impossible。

代码:

  1. #include<set>
  2. #include<map>
  3. #include<cstdio>
  4. #include<utility>
  5. #include<cmath>
  6. #include<stack>
  7. #include<vector>
  8. #include<queue>
  9. #include<cstring>
  10. #include<string>
  11. #include<sstream>
  12. #include<iostream>
  13. #include<algorithm>
  14. #define ll long long
  15. #define ull unsigned long long
  16. using namespace std;
  17. const int maxn = +;
  18. const int seed = ;
  19. const int MOD = ;
  20. const int INF = 0x3f3f3f3f;
  21. struct Edge{
  22. int to,val;
  23. Edge(int _to = ,int _val = ):to(_to),val(_val){}
  24. };
  25. vector<Edge> G[maxn];
  26. int w,h,turn[][] = {,,,-,,,-,};
  27. set<int> grave,bh;
  28. int point(int x,int y){
  29. return (x - ) * h + y;
  30. }
  31. void addEdge(int u,int v,int val){
  32. G[u].push_back(Edge(v,val));
  33. }
  34.  
  35. bool vis[maxn];
  36. int cnt[maxn],dist[maxn];
  37.  
  38. bool spfa(int start,int n){
  39. memset(vis,false,sizeof(vis));
  40. for(int i = ;i <= n;i++) dist[i] = INF;
  41. vis[start] = true;
  42. dist[start] = ;
  43. queue<int> q;
  44. while(!q.empty()) q.pop();
  45. q.push(start);
  46. memset(cnt,,sizeof(cnt));
  47. cnt[start] = ;
  48. while(!q.empty()){
  49. int u = q.front();
  50. q.pop();
  51. vis[u] = false;
  52. for(int i = ;i < G[u].size();i++){
  53. int v = G[u][i].to;
  54. if(dist[v] > dist[u] + G[u][i].val){
  55. dist[v] = dist[u] + G[u][i].val;
  56. if(!vis[v]){
  57. vis[v] = true;
  58. q.push(v);
  59. if(++cnt[v] > n) return false;
  60. }
  61. }
  62. }
  63. }
  64. return true;
  65. }
  66.  
  67. int main(){
  68. int g,e;
  69. while(scanf("%d%d",&w,&h) != EOF && w + h){
  70. grave.clear();
  71. bh.clear();
  72. for(int i = ;i <= point(w,h);i++) G[i].clear();
  73. scanf("%d",&g);
  74. while(g--){
  75. int x,y;
  76. scanf("%d%d",&x,&y);
  77. x++,y++;
  78. grave.insert(point(x,y));
  79. }
  80. scanf("%d",&e);
  81. while(e--){
  82. int x1,y1,x2,y2,w;
  83. scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&w);
  84. x1++,y1++,x2++,y2++;
  85. addEdge(point(x1,y1),point(x2,y2),w);
  86. bh.insert(point(x1,y1));
  87. }
  88. for(int i = ;i <= w;i++){
  89. for(int j = ;j <= h;j++){
  90. int now = point(i,j);
  91. if(i == w && j == h) continue;
  92. if(grave.count(now)) continue;
  93. if(bh.count(now)) continue;
  94. for(int k = ;k < ;k++){
  95. int fx = i + turn[k][],fy = j + turn[k][];
  96. if(fx < || fx > w || fy < || fy > h) continue;
  97. int to = point(fx,fy);
  98. if(grave.count(to)) continue;
  99. else{
  100. addEdge(now,to,);
  101. }
  102. }
  103. }
  104. }
  105. bool never;
  106. never = spfa(point(,),point(w,h));
  107. if(!never){
  108. printf("Never\n");
  109. }
  110. else{
  111. if(dist[point(w,h)] >= INF) printf("Impossible\n");
  112. else printf("%d\n",dist[point(w,h)]);
  113. }
  114. }
  115. return ;
  116. }

ZOJ 3391 Haunted Graveyard(最短路负权回路)题解的更多相关文章

  1. Spfa 求含负权边的最短路 + 判断是否存在负权回路

    在Bellman-Ford算法之后,我们总算迎来了spfa算法,其实就如同堆优化Dijkstra算法之于朴素版Dijkstra算法,spfa算法仅仅是对Bellman-Ford算法的一种优化,但是在形 ...

  2. poj 3259 bellman最短路推断有无负权回路

    Wormholes Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 36717   Accepted: 13438 Descr ...

  3. bellman-ford(可判负权回路+记录路径)

    #include<iostream> #include<cstdio> using namespace std; #define MAX 0x3f3f3f3f #define ...

  4. Bellman-ford算法与SPFA算法思想详解及判负权环(负权回路)

    我们先看一下负权环为什么这么特殊:在一个图中,只要一个多边结构不是负权环,那么重复经过此结构时就会导致代价不断增大.在多边结构中唯有负权环会导致重复经过时代价不断减小,故在一些最短路径算法中可能会凭借 ...

  5. [ACM] POJ 3259 Wormholes (bellman-ford最短路径,推断是否存在负权回路)

    Wormholes Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 29971   Accepted: 10844 Descr ...

  6. POJ 3259 Wormholes Bellman_ford负权回路

    Description While exploring his many farms, Farmer John has discovered a number of amazing wormholes ...

  7. SPFA穿越虫洞——负权回路得判断

    poj3259 题目大意:穿越虫洞可以回到过去(时间--)所以能不能让时间倒流呢,就是判断有没有负权回路这次尝试用SPFA算法,也可以复习一下链式前向星 准备工作,队列q,spfa算法得有点就在于这个 ...

  8. POJ 3259 Wormholes 邻接表的SPFA判断负权回路

    http://poj.org/problem?id=3259 题目大意: 一个农民有农场,上面有一些虫洞和路,走虫洞可以回到 T秒前,而路就和平常的一样啦,需要花费时间走过.问该农民可不可能从某个点出 ...

  9. Haunted Graveyard ZOJ - 3391(SPFA)

    从点(n,1)到点(1,m)的最短路径,可以转换地图成从(1,1)到(n,m)的最短路,因为有负权回路,所以要用spfa来判负环, 注意一下如果负环把终点包围在内的话, 如果用负环的话会输出无穷,但是 ...

随机推荐

  1. Mybatis 搭配 阿里druid连接池 连接 oracle 或 mysql

    DRUID介绍 DRUID是阿里巴巴开源平台上一个数据库连接池实现,它结合了C3P0.DBCP.PROXOOL等DB池的优点,同时加入了日志监控,可以很好的监控DB池连接和SQL的执行情况,可以说是针 ...

  2. js封装正则验证

    //根据不同的验证内容,返回相应的正则表达式 function returnRegString(regName) { if (regName == "email") { retur ...

  3. IFS二次开发03——Item

    在TFS 中把每个文件夹被抽象成“ItemSet”或“Item”,相对于父级目录来讲就是Item ,相对于子级目录来讲就是“ItemSet”.每个文件都被抽象成“Item”. //连接TFS stri ...

  4. CH601后缀数组【Trie树】

    内含字典树创建及查询模板 1601 前缀统计 0x10「基本数据结构」例题 描述 给定N个字符串S1,S2...SN,接下来进行M次询问,每次询问给定一个字符串T,求S1-SN中有多少个字符串是T的前 ...

  5. Django - 项目总结

    总结: 基础,进阶,项目 Django - 练习(图书管理系统) 前后端分离得项目: vue + rest framework 项目: 图书增删改查页面 BBS + BLOG系统 CRM系统   在线 ...

  6. 大话https演化过程(对称加密、非对称加密、公钥、私钥、数字签名、数字证书)

    大话https演化过程(包括概念:对称加密.非对称加密.公钥.私钥.数字签名.数字证书.https访问全过程)   在网络上发送数据是非常不安全的,非常容易被劫持或是被篡改,所以每次定向发送数据你都可 ...

  7. LoadRunner-常用的函数

    LoadRunner中,常用的函数有很多,这里只介绍编写性能测试脚本过程中那些必然用到的函数.本文重点关注这些典型函数的应用场合及注意点,至于函数详细使用说明请参见LoadRunner帮助文档. 1. ...

  8. go-002-语言结构

    Go 语言的基础组成有以下几个部分: 包声明package,必须在源文件中非注释的第一行指明这个文件属于哪个包, 引入包import,在开头部位使用 import 导入包,单个包 import “fm ...

  9. 配置Tomcat直接显示目录结构和文件列表

    Tomcat是直接显示目录结构和文件列表,只是在配置里面给关闭了. 关键在这里:\conf\web.xml 这个文件有一段配置直接控制Tomcat是允许显示目录结构和文件列表. <servlet ...

  10. HDU1575:Tr A(矩阵快速幂模板题)

    http://acm.hdu.edu.cn/showproblem.php?pid=1575   #include <iostream> #include <string.h> ...