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.. MW+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.
题目意思:对于t组输入输出,有N个点,M条双向通路,K个虫洞。虫洞是一个单向的通路。问能否从某一个点出发,通过一些路径和虫洞,返回到出发点,并且时间还要早于出发时间,这样他就能够遇到他自己了。
解题思路:又是John,想都不用想又是USACO的题,美国果然是农业立国啊。在第二组样例中,John沿着1->2->3->1,从第一个点出发回到第一个点,所需时间为-1,这样他就能够遇到自己了。这该怎么思考?遇到虫洞会回到过去,时间回溯。实际上就是要求判断一个带有负权的有向网中是否存在负权值回路,
我们知道可以使用Bellman-Ford可以判断是否存在负环,因为出现了负值回路后会不断的松弛。这里我们用优化后的SPFA来实现。
原理:如果存在负权值回路,那么从源点到某一个点的最短路径可以无限缩短,某些顶点入队列将会超过N次(N为顶点个数)。
ps:代码有给出了另外一种判断是否有负环的方法,时间会更快。从任意一点出发求最短路,必定会求出到其他所有点的最短路,若其中某个点在一个负权回路中,那么它肯定会不断地走这个回路以使到这个点的花费越小越好,这时候该点到出发点的距离就会为负值,所以只需从一个点开始便能找到是否存在负回路,这里我们就只看从源点到源点的dis就可以了。
 
 #include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
#define INF 0x3f3f3f3f
#define maxs 10010
using namespace std;
struct node
{
int to;
int w;
} t;
vector<node>Map[maxs];
int dis[maxs];
int vis[maxs];
int n,m,k;
void add(int s,int e,int w)
{
t.to=e;
t.w=w;
Map[s].push_back(t);
}
void init()
{
int i;
memset(dis,INF,sizeof(dis));
memset(vis,,sizeof(vis));
for(i=; i<=n; i++)
{
Map[i].clear();
}
}
int SPFA(int s)
{
int cnt[maxs]= {};///记录每个点入队次数
int i;
dis[s]=;
vis[s]=;
queue<int>q;
q.push(s);
cnt[s]++;
while(!q.empty())
{
int u=q.front();
/*if(cnt[u]>=n)
{
return 0;///这里用来判断入队列是否超过N次
}*/
q.pop();
vis[u]=;
for(i=; i<Map[u].size(); i++)
{
int to=Map[u][i].to;
if(dis[to]>dis[u]+Map[u][i].w)
{
dis[to]=dis[u]+Map[u][i].w;///松弛操作
if(dis[]<)///这种判断是否有负环的更快。如果起始点的dis[s]<0说明存在负环
{
return ;
}
if(!vis[to])
{
vis[to]=;
q.push(to);
cnt[to]++;
}
}
}
}
return ;
}
int main()
{
int t,i,j,u,v,w;
scanf("%d",&t);
for(i=; i<=t; i++)
{
scanf("%d%d%d",&n,&m,&k);
init();
while(m--)
{
scanf("%d%d%d",&u,&v,&w);
add(u,v,w);
add(v,u,w);
}
while(k--)
{
scanf("%d%d%d",&u,&v,&w);
add(u,v,-w);///虫洞时间取负值
}
if(SPFA())
{
printf("NO\n");
}
else
{
printf("YES\n");
}
}
return ;
}

这里再附上使用邻接矩阵和Bellman-Ford算法的代码。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define inf 0x3f3f3f3f
struct Edge
{
int f;///起点
int t;///终点
int c;///距离
} edge[];
int dist[];
int n,m,h,cnt;
int bellman_ford()
{
memset(dist,inf,sizeof(dist));
dist[]=;///起点
int i,j;
for(j=; j<=n; j++)
{
for(i=; i<=cnt; i++)
{
if(dist[edge[i].t]>dist[edge[i].f]+edge[i].c)///松弛操作
{
dist[edge[i].t]=dist[edge[i].f]+edge[i].c;
}
}
}
int flag=;
for(i=; i<=cnt; i++)///遍历所有的边
{
if(dist[edge[i].t]>dist[edge[i].f]+edge[i].c)
{
flag=;///存在从源点可达的负权回路
break;
}
}
return flag;
}
int main()
{
int i,t;
scanf("%d",&t);
while(t--)
{
cnt=;
scanf("%d %d %d",&n,&m,&h);
int u,v,w;
for(i=; i<=m; i++)
{
cnt++;
scanf("%d %d %d",&u,&v,&w);
edge[cnt].f=u;
edge[cnt].t=v;
edge[cnt].c=w;
cnt++;
edge[cnt].f=v;
edge[cnt].t=u;
edge[cnt].c=w;
}
for(i=; i<=h; i++)
{
cnt++;
scanf("%d %d %d",&u,&v,&w);
edge[cnt].f=u;
edge[cnt].t=v;
edge[cnt].c=-w;
}
if(bellman_ford())
printf("NO\n");
else
printf("YES\n");
}
return ;
}
 

Wormholes POJ 3259(SPFA判负环)的更多相关文章

  1. Wormholes POJ - 3259 spfa判断负环

    //判断负环 dist初始化为正无穷 //正环 负无穷 #include<iostream> #include<cstring> #include<queue> # ...

  2. bzoj 1715: [Usaco2006 Dec]Wormholes 虫洞【spfa判负环】

    tag是假的,用了及其诡异的方法判负环 正权无向边和负权有向边的图 #include<iostream> #include<cstdio> #include<cstrin ...

  3. POJ - 3851-Wormholes(SPFA判负环)

    A friend of yours, an inventor, has built a spaceship recently and wants to explore space with it. D ...

  4. POJ 3259 Wormholes(SPFA判负环)

    题目链接:http://poj.org/problem?id=3259 题目大意是给你n个点,m条双向边,w条负权单向边.问你是否有负环(虫洞). 这个就是spfa判负环的模版题,中间的cnt数组就是 ...

  5. Poj 3259 Wormholes(spfa判负环)

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

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

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

  7. poj 1364 King(线性差分约束+超级源点+spfa判负环)

    King Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 14791   Accepted: 5226 Description ...

  8. BZOJ 1715: [Usaco2006 Dec]Wormholes 虫洞 DFS版SPFA判负环

    Description John在他的农场中闲逛时发现了许多虫洞.虫洞可以看作一条十分奇特的有向边,并可以使你返回到过去的一个时刻(相对你进入虫洞之前).John的每个农场有M条小路(无向边)连接着N ...

  9. spfa判负环

    bfs版spfa void spfa(){ queue<int> q; ;i<=n;i++) dis[i]=inf; q.push();dis[]=;vis[]=; while(!q ...

  10. 2018.09.24 bzoj1486: [HNOI2009]最小圈(01分数规划+spfa判负环)

    传送门 答案只保留了6位小数WA了两次233. 这就是一个简单的01分数规划. 直接二分答案,根据图中有没有负环存在进行调整. 注意二分边界. 另外dfs版spfa判负环真心快很多. 代码: #inc ...

随机推荐

  1. WebGl 一个缓冲区传递颜色和坐标(矩形)

    效果: 代码: <!DOCTYPE html> <html lang="en"> <head> <meta charset="U ...

  2. sqli-labs(less-11-16)

    POST登入 首先试试 uname=admin'# & passwd=1 登入成功 如果不知道用户名 ,注释符被过滤,可以从password入手 一般第一个登陆字段(一般是用户名)就用注释,第 ...

  3. 【非原创】ISBN码

    #include<stdio.h>int main(void){ char a[14],mod[12]="0123456789X"; #include <stdi ...

  4. 理解 ajax、fetch和axios

    背景 ajax fetch.axios 优缺点 ajax基于jquery,引入时需要引入庞大的jquery库,不符合当下前端框架,于是fetch替代了ajax 由于fetch是比较底层,需要我们再次封 ...

  5. 20155223 2016-2017-2《Java程序设计》课程总结

    20155223 2016-2017-2<Java程序设计>课程总结 每周作业链接汇总 预备作业1 预备作业2 预备作业3 第一周 第二周 第三周 第四周 第五周 第六周 第七周 第八周 ...

  6. sql语句-6-更新数据

  7. 解决 idea template jsp模板中使用自定义路径 模板不显示问题

    ${} 是一个模板中的关键字,所以建立时需要用 \ 注释即可正常显示  ${APP_PATH}

  8. Q&As:1.cocos2d-html5如何获得鼠标划过事件

    不喜欢按部就班学东西,感觉各种框架各种技术就应该是拿到手用的,这应该是导致我现在学了这么多却没一样精通的缘故吧. 发现自己喜欢在QQ群回答一些菜鸟的问题,就算自己不清楚也会乐意看代码帮助解决╮(╯_╰ ...

  9. 第五章Web应用与应用层协议

    Web应用与应用层协议 本篇博文中的主要参考文献是<计算机网络高级教程>,分别是吴功宜老先生和吴英教授合著.这部教程是我研究生老师所推荐的网络必读科目,由于该教程讲解的基础知识详细,但内容 ...

  10. 785. Is Graph Bipartite?

    Given an undirected graph, return true if and only if it is bipartite. Recall that a graph is bipart ...