POJ 3259 Wormholes【最短路/SPFA判断负环模板】
农夫约翰在探索他的许多农场,发现了一些惊人的虫洞。虫洞是很奇特的,因为它是一个单向通道,可让你进入虫洞的前达到目的地!他的N(1≤N≤500)个农场被编号为1..N,之间有M(1≤M≤2500)条路径,W(1≤W≤200)个虫洞。FJ作为一个狂热的时间旅行的爱好者,他要做到以下几点:开始在一个区域,通过一些路径和虫洞旅行,他要回到最开时出发的那个区域出发前的时间。也许他就能遇到自己了:)。为了帮助FJ找出这是否是可以或不可以,他会为你提供F个农场的完整的映射到(1≤F≤5)。所有的路径所花时间都不大于10000秒,所有的虫洞都不大于万秒的时间回溯。Input第1行:一个整数F表示接下来会有F个农场说明。 每个农场第一行:分别是三个空格隔开的整数:N,M和W 第2行到M+1行:三个空格分开的数字(S,E,T)描述,分别为:需要T秒走过S和E之间的双向路径。两个区域可能由一个以上的路径来连接。 第M +2到M+ W+1行:三个空格分开的数字(S,E,T)描述虫洞,描述单向路径,S到E且回溯T秒。OutputF行,每行代表一个农场 每个农场单独的一行,” YES”表示能满足要求,”NO”表示不能满足要求。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 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.
- #include<cstdio>
- #include<string>
- #include<cstdlib>
- #include<cmath>
- #include<iostream>
- #include<cstring>
- #include<set>
- #include<queue>
- #include<algorithm>
- #include<vector>
- #include<map>
- #include<cctype>
- #include<stack>
- #include<sstream>
- #include<list>
- #include<assert.h>
- #include<bitset>
- #include<numeric>
- #define debug() puts("++++")
- #define gcd(a,b) __gcd(a,b)
- #define lson l,m,rt<<1
- #define rson m+1,r,rt<<1|1
- #define fi first
- #define se second
- #define pb push_back
- #define sqr(x) ((x)*(x))
- #define ms(a,b) memset(a,b,sizeof(a))
- #define sz size()
- #define be begin()
- #define mp make_pair
- #define pu push_up
- #define pd push_down
- #define cl clear()
- #define lowbit(x) -x&x
- #define all 1,n,1
- #define rep(i,x,n) for(int i=(x); i<=(n); i++)
- #define in freopen("in.in","r",stdin)
- #define out freopen("out.out","w",stdout)
- using namespace std;
- typedef long long LL;
- typedef unsigned long long ULL;
- typedef pair<int,int> P;
- const int INF = 0x3f3f3f3f;
- const LL LNF = 1e18;
- const int maxn = 1e5+;
- const int maxm = 1e6 + ;
- const double PI = acos(-1.0);
- const double eps = 1e-;
- const int dx[] = {-,,,,,,-,-};
- const int dy[] = {,,,-,,-,,-};
- int dir[][] = {{,},{,-},{-,},{,}};
- const int mon[] = {, , , , , , , , , , , , };
- const int monn[] = {, , , , , , , , , , , , };
- int tot,n,m,x,s;
- int u,v,w;
- int dis[maxn];
- int cnt[maxn],vis[maxn];
- struct cmp
- {
- bool operator()(int a,int b)
- {
- return dis[a] > dis[b];
- }
- };
- int head[maxn];
- struct node
- {
- int v,w,nxt;
- }e[maxn];
- void init()
- {
- tot=;
- ms(cnt,);
- ms(head,-);
- ms(dis,INF);//求最长路径开始设为0
- ms(vis,);
- }
- void add(int u,int v,int w)
- {
- e[tot].v=v;
- e[tot].w=w;
- e[tot].nxt=head[u];
- head[u]=tot++;
- }
- int spfa(int s)
- {
- queue<int> q;
- vis[s]=;
- dis[s]=;
- cnt[s]++;
- q.push(s);
- while(!q.empty())
- {
- int u = q.front(); q.pop();
- vis[u]=; //
- for(int i=head[u];i!=-;i=e[i].nxt)
- {
- int v = e[i].v;
- if(dis[v] > dis[u] + e[i].w)
- {
- dis[v] = dis[u] + e[i].w;
- if(!vis[v])
- {
- vis[v]=;
- q.push(v);
- if(++cnt[v]>n) return ;//有负环
- }
- }
- }
- }
- return ;
- }
- int main()
- {
- int t;
- scanf("%d",&t);
- while(t--)
- {
- scanf("%d%d%d",&n,&m,&w);
- init();
- int a,b,c;
- for(int i=;i<=m;i++)
- {
- scanf("%d%d%d",&a,&b,&c);
- add(a,b,c);add(b,a,c);
- }
- for(int i=;i<=w;i++)
- {
- scanf("%d%d%d",&a,&b,&c);
- add(a,b,-c);
- }
- if(spfa()) puts("YES");
- else puts("NO");
- }
- }
- /*
- 【题意】
- 【类型】
- SPFA判断负环
- 【分析】
- spfa算法
- 我们都知道spfa算法是对bellman算法的优化,那么如何用spfa算法来判断负权回路呢?我们考虑一个节点入队的条件是什么,只有那些在前一遍松弛中改变了距离估计值的点,才可能引起他们的邻接点的距离估计值的改变。因此,用一个先进先出的队列来存放被成功松弛的顶点。同样,我们有这样的定理:“两点间如果有最短路,那么每个结点最多经过一次。也就是说,这条路不超过n-1条边。”(如果一个结点经过了两次,那么我们走了一个圈。如果这个圈的权为正,显然不划算;如果是负圈,那么最短路不存在;如果是零圈,去掉不影响最优值)。也就是说,每个点最多入队n-1次(这里比较难理解,需要仔细体会,n-1只是一种最坏情况,实际中,这样会很大程度上影响程序的效率)。
- 有了上面的基础,思路就很显然了,加开一个数组记录每个点入队的次数(num),然后,判断当前入队的点的入队次数,如果大于n-1,则说明存在负权回路。
- 【时间复杂度&&优化】
- 【trick】
- 【数据】
- */
POJ 3259 Wormholes【最短路/SPFA判断负环模板】的更多相关文章
- 解题报告:poj 3259 Wormholes(入门spfa判断负环)
Description While exploring his many farms, Farmer John has discovered a number of amazing wormholes ...
- Wormholes---poj3259(最短路 spfa 判断负环 模板)
题目链接:http://poj.org/problem?id=3259 题意是问是否能通过虫洞回到过去: 虫洞是一条单向路,不但会把你传送到目的地,而且时间会倒退Ts. 我们把虫洞看成是一条负权路,问 ...
- POJ 3259 Wormholes(最短路径,求负环)
POJ 3259 Wormholes(最短路径,求负环) Description While exploring his many farms, Farmer John has discovered ...
- POJ 3259 Wormholes ( SPFA判断负环 && 思维 )
题意 : 给出 N 个点,以及 M 条双向路,每一条路的权值代表你在这条路上到达终点需要那么时间,接下来给出 W 个虫洞,虫洞给出的形式为 A B C 代表能将你从 A 送到 B 点,并且回到 C 个 ...
- Wormholes POJ - 3259 spfa判断负环
//判断负环 dist初始化为正无穷 //正环 负无穷 #include<iostream> #include<cstring> #include<queue> # ...
- POJ3259 Wormholes(SPFA判断负环)
Description While exploring his many farms, Farmer John has discovered a number of amazing wormholes ...
- UVA 558 SPFA 判断负环
这个承认自己没看懂题目,一开始以为题意是形成环路之后走一圈不会产生负值就输出,原来就是判断负环,用SPFA很好用,运用队列,在判断负环的时候,用一个数组专门保存某个点的访问次数,超过了N次即可断定有负 ...
- spfa判断负环
会了spfa这么长时间竟然不会判断负环,今天刚回.. [例题]poj3259 题目大意:当农场主 John 在开垦他的农场时,他发现了许多奇怪的昆虫洞.这些昆虫洞是单向的,并且可以把你从入口送到出口, ...
- spfa 判断负环 (转载)
当然,对于Spfa判负环,实际上还有优化:就是把判断单个点的入队次数大于n改为:如果总的点入队次数大于所有点两倍 时有负环,或者单个点的入队次数大于sqrt(点数)有负环.这样时间复杂度就降了很多了. ...
随机推荐
- Jade模板引擎学习(二)语法:代码、变量、循环、过滤器及mixin
Jade语法 一.代码 不会被缓冲代码 ul - for(var i=0; i; i++) li Jade Engine 会转换为: <ul> <li>Jade Engine& ...
- C# 后台获取请求来源、文件下载
文件流下载文件 void BigFileDownload() { try { string FileName = "测试.docx"; string filePath = Page ...
- redis启动脚本
#!/bin/sh # # Simple Redis init.d script conceived to work on Linux systems # as it does use of the ...
- PHP is_null,empty以及isset,unset的区别
1.empty 判断一个变量是否为“空”.null.false.00.0.’0′.』.为以上值的变量在检测時都将返回true. 2.isset 判断一个变量是否已经设置.0.00.’0′.』.’ ‘. ...
- bzoj 3028 母函数
首先我们可以求出来所有食物的母函数: 汉堡:f(x)=1/(1-x^2). 可乐:f(x)=1+x. 鸡腿:f(x)=1+x+x^2. 蜜桃多:f(x)=x/(1-x^2). 鸡块:f(x)=1/(1 ...
- TDD随想录
TDD随想录 谨以本文献给TDD的开创者与传播者 本文纯属个人经历,如有雷同纯属巧合 我从不觉得自己是一个好的程序员,甚至可能连合格都谈不上,不过在内心深处我却渴望着在编程这件事上获得成功. 可惜每次 ...
- js中的document.ready
1.概念 表示在dom结构绘制完成后执行,可能DOM元素关联的部分并未加载完 2.写法 $(document).on("ready",function(){ }) $(docume ...
- hdfs文件上传机制与namenode元数据管理机制
1.hdfs文件上传机制 文件上传过程: 1.客户端想NameNode申请上传文件, 2.NameNode返回此次上传的分配DataNode情况给客户端 3.客户端开始依向dataName上传对应 ...
- 【POJ2420】A star not a tree?
蒟蒻开始学模拟退火…… 起初一直不肯学,因为毕竟玄学算法…… 哎呀玄学怎么就没用呢?对不对? #include<iostream> #include<cstdio> #incl ...
- Makefile 跟着走快点
引言 - 从"HelloWorld"开始 Makefile 是Linux C 程序开发最重要的基本功. 代表着整个项目编译和最终生成过程.本文重点是带大家了解真实项目中那些简易的 ...