【原创】POJ 3259 Wormholes(Bellman-Ford) && 简介Bellman-Ford算法

时间:2023-02-14 16:47:22

【原创】

题目大意

John有N个农场,一共有M条边,在农场上出现了W个虫洞(W是一条边),其中M是双向普通边,W是单向虫洞边。John穿行于农场之间每经过一条边(S到E)的时间为+T,每经过虫洞会时间倒流,经过-T。问John会不会在某一刻看到以前的自己。这个题目即问的是,存不存在负权环。bollman_ford

先粘一下百度百科的话:

Bellman - ford算法是求含负权图的单源最短路径算法,效率很低,但代码很容易写。其原理为持续地进行松弛(原文是这么写的,为什么要叫松弛,争议很大),在每次松弛时把每条边都更新一下,若在n-1次松弛后还能更新,则说明图中有负环,因此无法得出结果,否则就完成。Bellman - ford算法有一个小优化:每次松弛先设一个标识flag,初值为FALSE,若有边更新则赋值为TRUE,最终如果还是FALSE则直接成功退出。Bellman-ford算法浪费了许多时间去做没有必要的松弛,而SPFA算法用队列进行了优化,效果十分显著,高效难以想象。SPFA还有SLF,LLL,滚动数组等优化。

首先指出,图的任意一条最短路径既不能包含负权回路,也不会包含正权回路,因此它最多包含|v|-1条边。
其次,从源点s可达的所有顶点如果 存在最短路径,则这些最短路径构成一个以s为根的最短路径树。Bellman-Ford算法的迭代松弛操作,实际上就是按顶点距离s的层次,逐层生成这棵最短路径树的过程。
在对每条边进行第1遍松弛的时候,生成了从s出发,层次至多为1的那些树枝。也就是说,找到了与s至多有1条边相联的那些顶点的最短路径;对每条边进行第2遍松弛的时候,生成了第2层次的树枝,就是说找到了经过2条边相连的那些顶点的最短路径……。因为最短路径最多只包含|v|-1 条边,所以,只需要循环|v|-1 次。
每实施一次松弛操作,最短路径树上就会有一层顶点达到其最短距离,此后这层顶点的最短距离值就会一直保持不变,不再受后续松弛操作的影响。(但是,每次还要判断松弛,这里浪费了大量的时间,怎么优化?单纯的优化是否可行?)
注意:上述只对正权图有效。如果存在负权不一定第i次就能确定最短路,且与边的顺序有关。
如果没有负权回路,由于最短路径树的高度最多只能是|v|-1,所以最多经过|v|-1遍松弛操作后,所有从s可达的顶点必将求出最短距离。如果 d[v]仍保持 +∞,则表明从s到v不可达。
如果有负权回路,那么第 |v| 遍松弛操作仍然会成功,这时,负权回路上的顶点不会收敛。

这其他的不多说,先说一下松弛计算,其实就是更新距离嘛,这种思想在运筹学好像称之为松弛,我们知道,假如图中的边全部为正权边就一定会有最短路径,假如存在负权环,那么每走一圈,起点的权值就会比原来小,那么你走无数圈,你的权值就会无限减小。那么百度百科的意思就是,你先做标准次数的距离更新(理论上讲已经无法再更新了),假如你再一次更新距离,如果还能更新,就一定存在负权环咯。

 /*题目大意
John有N个农场,一共有M条边,在农场上出现了W个虫洞(W是一条边),其中M是双向普通边
,W是单向虫洞边。John穿行于农场之间每经过一条边(S到E)的时间为+T,每经过虫洞会时
间倒流,经过-T。问John会不会在某一刻看到以前的自己。
这个题目即问的是,存不存在负权环。bollman_ford
*/ #include<cstdio>
#include<iostream>
#include<memory.h>
#define max 9999999
using namespace std;
int n,m,w,top;
typedef struct
{
int x,y,t;
} e;
e edge[]; bool bellman_ford(int en)//en = top-1,即边的数量
{
int dis[],u,v,w;
for(int i=;i<=n;i++) dis[i] = max;
dis[] = ;
for(int i=;i<n-;i++)    //百科说:首先指出,图的任意一条最短路径既不能包含负权回路,也不会包含正权回路,因此它最多包含|v|-1条边。
{
//for(int k=1;k<=n;k++) printf("%d ",dis[k]);
for(int j = ;j <= en;j++)
{
u = edge[j].x;
v = edge[j].y;
w = edge[j].t;
if(dis[u]<max && dis[u]+w < dis[v])
{
dis[v] = dis[u]+w;
}
}
}
for(int i=;i<=en;i++)
{
u = edge[i].x;
v = edge[i].y;
w = edge[i].t;
if(dis[u]<max && dis[u]+w<dis[v])
{
return true;//极限更新n-1,我们再更新en次,如果还能再更新,那返回TRUE表示存在负权环
}
}
return false;//不能再更新了,返回FALSE
}
int main(){
int T;
scanf("%d", &T);
while(T--){
top = ;
scanf("%d %d %d", &n, &m, &w);
for(int i=; i<m; i++){
int a,b,c;
scanf("%d %d %d", &a, &b, &c);
edge[top].x = a;
edge[top].y = b;
edge[top].t = c;
top++;
edge[top].x = b; //这里一定要注意,普通的边是双向的,所以要重新反过来存一次
edge[top].y = a;
edge[top].t = c;
top++;
}
for(int i=; i<w; i++){
int a,b,c;
scanf("%d %d %d", &a, &b, &c);
edge[top].x = a;
edge[top].y = b;
edge[top].t = -c; //虫洞是负的且是单向所以 取负 只用存一次
top++;
}
if(bellman_ford(top-)) printf("YES\n");
else printf("NO\n");
}
}

 

【原创】POJ 3259 Wormholes(Bellman-Ford) && 简介Bellman-Ford算法的更多相关文章

  1. ACM&colon; POJ 3259 Wormholes - SPFA负环判定

     POJ 3259 Wormholes Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu   ...

  2. 最短路&lpar;Bellman&lowbar;Ford&rpar; POJ 3259 Wormholes

    题目传送门 /* 题意:一张有双方向连通和单方向连通的图,单方向的是负权值,问是否能回到过去(权值和为负) Bellman_Ford:循环n-1次松弛操作,再判断是否存在负权回路(因为如果有会一直减下 ...

  3. poj - 3259 Wormholes &lpar;bellman-ford算法求最短路)

    http://poj.org/problem?id=3259 农夫john发现了一些虫洞,虫洞是一种在你到达虫洞之前把你送回目的地的一种方式,FJ的每个农场,由n块土地(编号为1-n),M 条路,和W ...

  4. POJ 3259 Wormholes(最短路径,求负环)

    POJ 3259 Wormholes(最短路径,求负环) Description While exploring his many farms, Farmer John has discovered ...

  5. POJ 3259 Wormholes (Bellman&lowbar;ford算法)

    题目链接:http://poj.org/problem?id=3259 Wormholes Time Limit: 2000MS   Memory Limit: 65536K Total Submis ...

  6. poj 3259 Wormholes

    题目连接 http://poj.org/problem?id=3259 Wormholes Description While exploring his many farms, Farmer Joh ...

  7. POJ 3259 Wormholes(最短路,判断有没有负环回路)

    Wormholes Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 24249   Accepted: 8652 Descri ...

  8. POJ 3259——Wormholes——————【最短路、SPFA、判负环】

    Wormholes Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit St ...

  9. POJ 3259 Wormholes Bellman题解

    版权声明:本文作者靖心,靖空间地址:http://blog.csdn.net/kenden23/.未经本作者同意不得转载. https://blog.csdn.net/kenden23/article ...

随机推荐

  1. golang开发环境&lpar;2016&period;9&period;16&rpar;

    一.windows下安装 1.下载go1.7.3.windows-amd64.msi,建议默认安装到‘C:\Go\’ 2.环境变量 变量 值 说明 Path C:\Go\bin 安装程序默认会设置,如 ...

  2. ANDROID开发之问题积累及解决方案(一)

    一.activity跳转及传值 当进行activity之间的跳转时我们会遇到这样的问题.首先熟悉下activity之间跳转.Activity跳转与传值,主要是通过Intent类来连接多个Activit ...

  3. Linux下配置SSL &lpar;转&rpar;

    没有安装apache的情况: 首先安装SSL,再编译安装Apache,再配置证书即可 1.下载apache和openssl 网址:http://www.apache.org http://www.op ...

  4. git--创建空的分支

    背景:项目进行中,需要创建一个空分支.在Git中创建分支,是必须有一个父节点的,也就是说必须在已有的分支上来创建新的分支,如果你的工程已经进行了一段时间,这个时候是无法创建空分支的. 解决方法: 使用 ...

  5. Linux下安装PCRE

    原文链接:https://www.linuxidc.com/Linux/2015-03/114986.htm PCRE(Perl Compatible Regular Expressions)是一个轻 ...

  6. Unicode 字符串排序规则(一):如何确定单个字符的顺序

    一.一个具体的例子引发的问题 当今是国际化的时代,多种语言可能同时显示在屏幕上.比如一个人可能喜欢听华语歌.英文歌.韩文歌和日语歌,又比如他的联系人中有中国人.英国人.日本人.韩国人以及有英文名字的中 ...

  7. win7 没有权限使用网络资源

    局域网下同一工作组电脑无法访问 提示"....没有权限使用网络资源...." 一.组策略 win + R 输入gpedit.msc并回车,打开本地组策略编辑器 按如下展开 计算机配 ...

  8. css的overflow属性

    原文:https://www.jianshu.com/p/67b536fc67c1 ------------------------------------------- 事实上我挺长一段时间都没弄清 ...

  9. 设计模式-生成者模式之c&num;代码

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  10. 3YAdmin-专注通用权限控制与表单的后台管理系统模板

    3YAdmin基于React+Antd构建.GitHub搜索React+Antd+Admin出来的结果没有上百也有几十个,为什么还要写这个东西呢? 一个后台管理系统的核心我认为应该是权限控制,表单以及 ...