Description

While exploring his many farms, Farmer John has discovered a number of amazing wormholes. A wormhole is very peculiar because it is a one-way path that delivers you to its destination at a time that is BEFORE you entered the wormhole! Each of FJ's farms comprises N (1 ≤ N ≤ 500) fields conveniently numbered 1..NM (1 ≤ M ≤ 2500) paths, and W (1 ≤ W≤ 200) wormholes.

As FJ is an avid time-traveling fan, he wants to do the following: start at some field, travel through some paths and wormholes, and return to the starting field a time before his initial departure. Perhaps he will be able to meet himself :) .

To help FJ find out whether this is possible or not, he will supply you with complete maps to F (1 ≤ F ≤ 5) of his farms. No paths will take longer than 10,000 seconds to travel and no wormhole can bring FJ back in time by more than 10,000 seconds.

Input

Line 1: A single integer, FF farm descriptions follow. 
Line 1 of each farm: Three space-separated integers respectively: NM, and W 
Lines 2..M+1 of each farm: Three space-separated numbers (SET) that describe, respectively: a bidirectional path between S and E that requires T seconds to traverse. Two fields might be connected by more than one path. 
Lines M+2..M+W+1 of each farm: Three space-separated numbers (SET) that describe, respectively: A one way path from S to E that also moves the traveler back T seconds.

Output

Lines 1..F: For each farm, output "YES" if FJ can achieve his goal, otherwise output "NO" (do not include the quotes).

Sample Input

2
3 3 1
1 2 2
1 3 4
2 3 1
3 1 3
3 2 1
1 2 3
2 3 4
3 1 8

Sample Output

NO
YES

Hint

For farm 1, FJ cannot travel back in time. 
For farm 2, FJ could travel back in time by the cycle 1->2->3->1, arriving back at his starting location 1 second before he leaves. He could start from anywhere on the cycle to accomplish this.
解题思路:本题可用floyd或者spfa算法来判断是否有负环。题意:有f个农场,每个农场有n块地,其间有m条路,w条虫洞,穿过虫洞之后相应的时间会倒退t秒,问是否可以从某块地出发到达另一块地之后通过虫洞逆流时间回到当初出发的那个时间点。怎么建图呢?建m条双向边,边权为正数,建k条单向边,边权为负数(时光逆流)。显然,我们只需判断整个图中是否存在一个权值之和为负数的回路即可。因为若存在了负环,沿着回路走,时间就会不断地减少,那么FJ就肯定能遇到当初那个时刻出发的自己。
spfa核心思想:构建一个队列,将松弛成功且不在队列的点加入队列中,同时将顶点v的入队次数加1并标记为true,表示该顶点在当前队列中,避免后面的顶点重复入队造成更新时间上的浪费,然后每出队一个点就将其标记为false,因为出队的顶点可能会对前面已更新的点到源点的距离有影响并可能再次入队,这样直到队列为空。如果队列中的某个顶点入队次数超过n次,就说明存在一个负环。为什么是大于n呢?如果是大于n-1,那么任意的单节点的图会被判定为存在负环,综合考虑取>n。
AC代码(141ms):
 #include<iostream>
#include<cstdio>
#include<queue>
#include<string.h>
using namespace std;
const int maxn=;
int T,x,y,z,n,m,k,u,v,w,cnt[maxn],dis[maxn];vector<int> v1[maxn],v2[maxn];bool vis[maxn];queue<int> que;
bool spfa(int s){
while(!que.empty())que.pop();
memset(vis,false,sizeof(vis));
que.push(s),vis[s]=true,cnt[s]++,dis[s]=;//注意:自己到本身的时间为dis[s]=0,同时累计每个顶点的入队次数,用于判负环
while(!que.empty()){
u=que.front(),que.pop(),vis[u]=false;
for(size_t j=;j<v1[u].size();++j){
v=v1[u][j],w=v2[u][j];
if(dis[u]+w<dis[v]){//松弛
dis[v]=dis[u]+w;
if(!vis[v]){
que.push(v),vis[v]=true;
if(++cnt[v]>n)return true;//如果第n+1次仍然更新,则存在负圈
}
}
}
}
return false;
}
int main(){
while(~scanf("%d",&T)){
while(T--){
scanf("%d%d%d",&n,&m,&k);memset(cnt,,sizeof(cnt));
for(int i=;i<=n;++i)v1[i].clear(),v2[i].clear();
for(int i=;i<=n;++i)dis[i]=2e9;
while(m--){
scanf("%d%d%d",&x,&y,&z);//建双向边
v1[x].push_back(y),v1[y].push_back(x);
v2[x].push_back(z),v2[y].push_back(z);
}
while(k--){
scanf("%d%d%d",&x,&y,&z);//建单向边,权值为负数,表示时间倒流
v1[x].push_back(y);
v2[x].push_back(-z);
}
if(spfa())puts("YES");
else puts("NO");
}
}
return ;
}

解题报告:poj 3259 Wormholes(入门spfa判断负环)的更多相关文章

  1. poj 3259 Wormholes【spfa判断负环】

    Wormholes Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 36729   Accepted: 13444 Descr ...

  2. (简单) POJ 3259 Wormholes,SPFA判断负环。

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

  3. Poj 3259 Wormholes(spfa判负环)

    Wormholes Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 42366 Accepted: 15560 传送门 Descr ...

  4. POJ 3259 Wormholes【bellman_ford判断负环——基础入门题】

    链接: http://poj.org/problem?id=3259 http://acm.hust.edu.cn/vjudge/contest/view.action?cid=22010#probl ...

  5. poj 3259 Wormholes(bellman-ford判断负环)

    题目链接:http://poj.org/problem?id=3259 题目就是问你能否回到原点而且时间还倒回去了.题目中有些路中有单向的虫洞能让时间回到过去 所以只要将虫洞这条边的权值赋为负然后再判 ...

  6. POJ 3259 Wormholes【Bellman_ford判断负环】

    题意:给出n个点,m条正权的边,w条负权的边,问是否存在负环 因为Bellman_ford最多松弛n-1次, 因为从起点1终点n最多经过n-2个点,即最多松弛n-1次,如果第n次松弛还能成功的话,则说 ...

  7. bzoj 1715: [Usaco2006 Dec]Wormholes 虫洞 -- spfa判断负环

    1715: [Usaco2006 Dec]Wormholes 虫洞 Time Limit: 5 Sec  Memory Limit: 64 MB 注意第一次加边是双向边第二次是单向边,并且每次询问前数 ...

  8. POJ 3259 Wormholes【最短路/SPFA判断负环模板】

    农夫约翰在探索他的许多农场,发现了一些惊人的虫洞.虫洞是很奇特的,因为它是一个单向通道,可让你进入虫洞的前达到目的地!他的N(1≤N≤500)个农场被编号为1..N,之间有M(1≤M≤2500)条路径 ...

  9. poj 2049(二分+spfa判负环)

    poj 2049(二分+spfa判负环) 给你一堆字符串,若字符串x的后两个字符和y的前两个字符相连,那么x可向y连边.问字符串环的平均最小值是多少.1 ≤ n ≤ 100000,有多组数据. 首先根 ...

随机推荐

  1. wxpython中控件对键盘输入无响应的可能原因

    问题描述: 开发环境:Win7 32bit + Python2.7.6 + WxPython 3.0.1-b20140707 开发某初级CAD软件中,需要实现点击TreeCtrl控件的相应选择,实现G ...

  2. MapReduce算法形式二:去重(HashSet)

    案例二:去重(shuffle/HashSet等方法)shuffle主要针对的是key去重HashSet主要针对values去重

  3. java -jar 与nohup的区别

    ——作为java程序员,经常会遇到这样一个问题,打个jar包,测试或者上线生产,于是乎面临的选择来了,java –jar or nohup? 下面我来扒一扒: 一.    java -jar a.ja ...

  4. SyntaxError:Strict mode does not allow function declaration in a lexically nested statement.

    问题描述   使用react-native init创建了一个新项目,在package.json中使用的react-native的版本如下: "dependencies": { & ...

  5. 提升自身的iOS编程水平 (转载)

    阅读博客 在现在这个碎片化阅读流行的年代,博客的风头早已被微博盖过.而我却坚持写作博客,并且大量地阅读同行的iOS开发博客.博客的文章长度通常在3000字左右,许多iOS开发知识都至少需要这样的篇幅才 ...

  6. redis---01

    redis是什么: redis是开源,BSD许可,高级的key-value存储系统. 可以用来存储字符串,哈希结构,链表,集合,因此,常用来提供数据结构服务. redis和memcached相比,的独 ...

  7. SILVERLIGHT实现对HTML DOM的访问

    实现对HTML DOM的访问.Silverlight 2在命名空间System.Windows.Browser下内置了很多对于HTML DOM访问和操作的支持,我们最常用的一个对象是HtmlEleme ...

  8. Oracle:impdb导入

    最近有现场给我一份用expdp导出dmp文件,我用imp导入时,报错.因为导出dmp的数据库是11g,导入的数据库也是11g, 但客户端安装的是10g,不能用imp导入:所以只能试着用impdp导入: ...

  9. 西交校赛 F. GZP and Poker

    F. GZP and Poker GZP often plays games with his friends.Today they went to a board game.There are n ...

  10. Opencv函数setMouseCallback鼠标事件响应

    用户通过鼠标对图像视窗最常见的操作有: 1. 左键单击按下 2. 左键单击抬起 3. 左键按下拖动 4. 鼠标指针位置移动 单次单击操作响应事件及顺序 Opencv中setMouseCallback( ...