博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
poj3259 Wormholes【最短路-bellman-负环】
阅读量:4332 次
发布时间:2019-06-06

本文共 3214 字,大约阅读时间需要 10 分钟。

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, 
F
F farm descriptions follow. 
Line 1 of each farm: Three space-separated integers respectively: 
N
M, and 
W 
Lines 2.. 
M+1 of each farm: Three space-separated numbers ( 
S
E
T) 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 ( 
S
E
T) 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
23 3 11 2 21 3 42 3 13 1 33 2 11 2 32 3 43 1 8
Sample Output
NOYES
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.

题意:走一条路会花费时间 走虫洞会时间倒流 问能不能走回起点的时候时间倒流

思路:其实就是判断有没有环 有环的话

看题的时候看了半天不知道起点到底是哪一个点

感觉现在bellman写的还挺顺手的了

一个加边的addedge函数 一个判断松弛的relax函数 

然后外面一个for循环遍历n-1次 里面的for循环松弛每一条边

再对每一条边判断能不能松弛 能就说明有环

有环其实就说明这个路径上有负的 

不然干吗要不停的重复走???

只有可以不断减小才会形成环

WA了一发是因为加边的时候的cnt没有初始化

代码:

#include
#include
#include
#include
#include
#include
#include
#include
#define inf 0x3f3f3f3fusing namespace std;int f, n, m, w, cnt;struct edge{ int s, e, t;}path[5205];long long d[505];void addedge(int s, int e, int t){ path[cnt].s = s; path[cnt].e = e; path[cnt].t = t; cnt++;}bool relax(int j){ if(d[path[j].e] > d[path[j].s] + path[j].t){ d[path[j].e] = d[path[j].s] + path[j].t; return true; } return false;}bool bellman(int sec){ memset(d, inf, sizeof(d)); d[sec] = 0; for(int i = 0; i < n - 1; i++){ bool flag = false; for(int j = 0; j < cnt; j++){ if(relax(j)) flag = true; } if(!flag) return false; } for(int i = 0; i < cnt; i++){ if(relax(i)) return true; } return false;}int main(){ cin>>f; while(f--){ cin>>n>>m>>w; cnt = 0; for(int i = 0; i < m; i++){ int a, b, c; cin>>a>>b>>c; addedge(a, b, c); addedge(b, a, c); } for(int i = 0; i < w; i++){ int a, b, c; cin>>a>>b>>c; addedge(a, b, -c); } if(bellman(1)) cout<<"YES\n"; else cout<<"NO\n"; } return 0;}

转载于:https://www.cnblogs.com/wyboooo/p/9643424.html

你可能感兴趣的文章
linux安装php-redis扩展(转)
查看>>
Vue集成微信开发趟坑:公众号以及JSSDK相关
查看>>
技术分析淘宝的超卖宝贝
查看>>
i++和++1
查看>>
react.js
查看>>
P1313 计算系数
查看>>
NSString的长度比较方法(一)
查看>>
Azure云服务托管恶意软件
查看>>
My安卓知识6--关于把项目从androidstudio工程转成eclipse工程并导成jar包
查看>>
旧的起点(开园说明)
查看>>
生产订单“生产线别”带入生产入库单
查看>>
crontab导致磁盘空间满问题的解决
查看>>
java基础 第十一章(多态、抽象类、接口、包装类、String)
查看>>
Hadoop 服务器配置的副本数量 管不了客户端
查看>>
欧建新之死
查看>>
自定义滚动条
查看>>
APP开发手记01(app与web的困惑)
查看>>
笛卡尔遗传规划Cartesian Genetic Programming (CGP)简单理解(1)
查看>>
mysql 日期时间运算函数(转)
查看>>
初识前端作业1
查看>>