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

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

代码:

#include<set>
#include<map>
#include<cstdio>
#include<utility>
#include<cmath>
#include<stack>
#include<vector>
#include<queue>
#include<cstring>
#include<string>
#include<sstream>
#include<iostream>
#include<algorithm>
#define ll long long
#define ull unsigned long long
using namespace std;
const int maxn = +;
const int seed = ;
const int MOD = ;
const int INF = 0x3f3f3f3f;
struct Edge{
int to,val;
Edge(int _to = ,int _val = ):to(_to),val(_val){}
};
vector<Edge> G[maxn];
int w,h,turn[][] = {,,,-,,,-,};
set<int> grave,bh;
int point(int x,int y){
return (x - ) * h + y;
}
void addEdge(int u,int v,int val){
G[u].push_back(Edge(v,val));
} bool vis[maxn];
int cnt[maxn],dist[maxn]; bool spfa(int start,int n){
memset(vis,false,sizeof(vis));
for(int i = ;i <= n;i++) dist[i] = INF;
vis[start] = true;
dist[start] = ;
queue<int> q;
while(!q.empty()) q.pop();
q.push(start);
memset(cnt,,sizeof(cnt));
cnt[start] = ;
while(!q.empty()){
int u = q.front();
q.pop();
vis[u] = false;
for(int i = ;i < G[u].size();i++){
int v = G[u][i].to;
if(dist[v] > dist[u] + G[u][i].val){
dist[v] = dist[u] + G[u][i].val;
if(!vis[v]){
vis[v] = true;
q.push(v);
if(++cnt[v] > n) return false;
}
}
}
}
return true;
} int main(){
int g,e;
while(scanf("%d%d",&w,&h) != EOF && w + h){
grave.clear();
bh.clear();
for(int i = ;i <= point(w,h);i++) G[i].clear();
scanf("%d",&g);
while(g--){
int x,y;
scanf("%d%d",&x,&y);
x++,y++;
grave.insert(point(x,y));
}
scanf("%d",&e);
while(e--){
int x1,y1,x2,y2,w;
scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&w);
x1++,y1++,x2++,y2++;
addEdge(point(x1,y1),point(x2,y2),w);
bh.insert(point(x1,y1));
}
for(int i = ;i <= w;i++){
for(int j = ;j <= h;j++){
int now = point(i,j);
if(i == w && j == h) continue;
if(grave.count(now)) continue;
if(bh.count(now)) continue;
for(int k = ;k < ;k++){
int fx = i + turn[k][],fy = j + turn[k][];
if(fx < || fx > w || fy < || fy > h) continue;
int to = point(fx,fy);
if(grave.count(to)) continue;
else{
addEdge(now,to,);
}
}
}
}
bool never;
never = spfa(point(,),point(w,h));
if(!never){
printf("Never\n");
}
else{
if(dist[point(w,h)] >= INF) printf("Impossible\n");
else printf("%d\n",dist[point(w,h)]);
}
}
return ;
}

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. nginx代理学习

    一.windows下nginx代理ftp服务器 我所在的开发环境里,nginx和ftp在同一台服务器. ftp根目录: nginx的配置: 在nginx.conf中加入: server { liste ...

  2. Nginx的安装和配置文件

    一.什么是Nginx 反向代理的高手,可以做web服务器.smtp服务器.ftp服务器,也可以做waf等等.原理,反向代理,收集client请求然后转发给自己lan内的服务器,将请求到的资源回转给客户 ...

  3. 配置maven使用nexus

    本文简单介绍使用配置maven使用nexus仓库,在团队中使用nexus,避免每个人都从中央仓库去下载依赖,节省带宽,提高下载速度,同时也减少了中央仓库的压力 配置在maven中使用nexus很简单( ...

  4. 【Android】Could not find XXX.apk!的解决方法

    昨天在Eclipse中导入一个Android工程后点击运行时出现了Could not find XXX.apk!的错误信息,具体错误提示如下:   到网上搜了好多方法,挨个尝试,最后都没解决但是,重启 ...

  5. hdu4975 网络流解方程组(网络流+dfs判环或矩阵DP)

    http://acm.hdu.edu.cn/showproblem.php?pid=4975 A simple Gaussian elimination problem. Time Limit: 20 ...

  6. python下几种打开文件的方式

    昨天看完了这本python进阶,感觉这本书对我启发很大,做了三张纸的笔记,方便我在遇到问题的时候翻阅,然后寻找可能的解决方案.作为一个使用Python一年的小白,虽然说不是小白,但是这一年来基本上是用 ...

  7. Linux系统下tomcat安装配置

    Linux系统中Tomcat的安装配置. 前提JDK已经安装好. 安装 下载tomcatwget http://mirrors.cnnic.cn/apache/tomcat/tomcat-8/v8.0 ...

  8. [面经] 南京SAP面试(下)

    上一篇讲到了一面结束,这一篇说说剩下的事情. 周三上午一面完了之后回去上班,本以为要等几天才会二面,结果那个经理M下午就打电话给我,约了第二天(周四)下午过去面试,会有Boss从上海过来面,办事效率还 ...

  9. Oracle性能优化之表压缩及并行提高效率的测试

    1.制作测试表 create table t1 as select * from FW_T_GTXLOG insert into t1 select * from t1; create table t ...

  10. Error:(12, 64) java: 未报告的异常错误java.io.IOException; 必须对其进行捕获或声明以便抛出

    Error:(12, 64) java: 未报告的异常错误java.io.IOException; 必须对其进行捕获或声明以便抛出 package com.test; import org.apach ...