题意:John的农场里field块地,path条路连接两块地,hole个虫洞,虫洞是一条单向路,不但会把你传送到目的地,而且时间会倒退Ts。我们的任务是知道会不会在从某块地出发后又回来,看到了离开之前的自己。

思路:

这题就是判断存不存在负环回路。

前M条是双向边,后面的W是单向的负边。

为了防止出现不连通,增加一个结点作为起点。起点到所有点的长度为0

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <vector>
using namespace std;
/*
* 单源最短路bellman_ford算法,复杂度O(VE)
* 可以处理负边权图。
* 可以判断是否存在负环回路。返回true,当且仅当图中不包含从源点可达的负权回路
* vector<Edge>E;先E.clear()初始化,然后加入所有边
* 点的编号从1开始
*/
const int INF = 0x3f3f3f3f;
const int MAXN = 550;
int dist[MAXN];
struct Edge
{
int u, v;
int cost;
Edge(int _u = 0, int _v = 0, int _cost = 0) :u(_u), v(_v), cost(_cost){}
};
vector<Edge> E;
bool bellman_ford(int start, int n)//点的编号从1开始
{
for (int i = 1; i <= n; i++)dist[i] = INF;
dist[start] = 0;
for (int i = 1; i<n; i++)//最多做n-1次
{
bool flag = false;
for (int j = 0; j<E.size(); j++)
{
int u = E[j].u;
int v = E[j].v;
int cost = E[j].cost;
if (dist[v]>dist[u] + cost)
{
dist[v] = dist[u] + cost;
flag = true;
}
}
if (!flag)return true;//没有负环回路
}
for (int j = 0; j<E.size(); j++)
if (dist[E[j].v]>dist[E[j].u] + E[j].cost)
return false;//第n次更新则有负环回路
return true;//没有负环回路
} int main()
{
int T;
int N, M, W;
int a, b, c;
scanf("%d", &T);
while (T--)
{
scanf("%d%d%d", &N, &M, &W);
E.clear();
while (M--)
{
scanf("%d%d%d", &a, &b, &c);
E.push_back(Edge(a, b, c));
E.push_back(Edge(b, a, c));
}
while (W--)
{
scanf("%d%d%d", &a, &b, &c);
E.push_back(Edge(a, b, -c));
}
for (int i = 1; i <= N; i++)
E.push_back(Edge(N + 1, i, 0));
if (!bellman_ford(N + 1, N + 1))printf("YES\n");
else printf("NO\n");
}
return 0;
}

(2) 如果一开始对所有顶点i,都把dist[i]初始化为0,那么可以检查出所有的负圈

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <vector>
using namespace std;
/*
* 单源最短路bellman_ford算法,复杂度O(VE)
* 可以处理负边权图。
* vector<Edge>E;先E.clear()初始化,然后加入所有边
* 点的编号从1开始
*/
const int INF = 0x3f3f3f3f;
const int MAXN = 550;
int dist[MAXN];
struct Edge
{
int u, v;
int cost;
Edge(int _u = 0, int _v = 0, int _cost = 0) :u(_u), v(_v), cost(_cost){}
};
vector<Edge> E;
bool bellman_ford(int n)//点的编号从1开始
{
for (int i = 1; i <= n; i++)dist[i] = 0;
for (int i = 1; i<n; i++)//最多做n-1次
{
bool flag = false;
for (int j = 0; j<E.size(); j++)
{
int u = E[j].u;
int v = E[j].v;
int cost = E[j].cost;
if (dist[v]>dist[u] + cost)
{
dist[v] = dist[u] + cost;
flag = true;
}
}
if (!flag)return true;//没有负环回路
}
for (int j = 0; j<E.size(); j++)
if (dist[E[j].v]>dist[E[j].u] + E[j].cost)
return false;//第n次更新则有负环回路
return true;//没有负环回路
} int main()
{
int T;
int N, M, W;
int a, b, c;
scanf("%d", &T);
while (T--)
{
scanf("%d%d%d", &N, &M, &W);
E.clear();
while (M--)
{
scanf("%d%d%d", &a, &b, &c);
E.push_back(Edge(a, b, c));
E.push_back(Edge(b, a, c));
}
while (W--)
{
scanf("%d%d%d", &a, &b, &c);
E.push_back(Edge(a, b, -c));
}
if (!bellman_ford(N))printf("YES\n");
else printf("NO\n");
}
return 0;
}

(3) SPFA

某个顶点进入队列的次数超过N,则有负环

#include <iostream>
#include <string.h>
#include <stdio.h>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
/*
* 单源最短路SPFA
*/
const int MAXN = 1010;
const int INF = 0x3f3f3f3f;
struct Edge
{
int v;
int cost;
Edge(int _v = 0, int _cost = 0) :v(_v), cost(_cost){}
}; vector<Edge> E[MAXN]; void addedge(int u, int v, int w)
{
E[u].push_back(Edge(v, w));
} bool vis[MAXN];
int cnt[MAXN];
int dist[MAXN]; bool SPFA(int start, int n)
{
memset(vis, false, sizeof(vis));
for (int i = 1; i <= n; i++)dist[i] = INF;
dist[start] = 0;
vis[start] = true;
queue<int>que;
while (!que.empty())que.pop();
que.push(start);
memset(cnt, 0, sizeof(cnt));
cnt[start] = 1;
while (!que.empty())
{
int u = que.front();
que.pop();
vis[u] = false;
for (int i = 0; i<E[u].size(); i++)
{
int v = E[u][i].v;
if (dist[v]>dist[u] + E[u][i].cost)
{
dist[v] = dist[u] + E[u][i].cost;
if (!vis[v])
{
vis[v] = true;
que.push(v);
if (++cnt[v]>n)return false;
//有负环回路
}
}
}
}
return true;
}
int main()
{
int T;
int N, M, W;
int a, b, c;
scanf("%d", &T);
while (T--)
{
scanf("%d%d%d", &N, &M, &W);
for (int i = 1; i <= N + 1; i++)E[i].clear();
while (M--)
{
scanf("%d%d%d", &a, &b, &c);
addedge(a, b, c);
addedge(b, a, c);
}
while (W--)
{
scanf("%d%d%d", &a, &b, &c);
addedge(a, b, -c);
}
for (int i = 1; i <= N; i++)
addedge(N + 1, i, 0);
if (!SPFA(N + 1, N + 1))printf("YES\n");
else printf("NO\n");
}
return 0;
}

POJ 3259 Wormholes(bellman_ford,判断有没有负环回路)的更多相关文章

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

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

  2. POJ 3259 Wormholes ( SPFA判断负环 && 思维 )

    题意 : 给出 N 个点,以及 M 条双向路,每一条路的权值代表你在这条路上到达终点需要那么时间,接下来给出 W 个虫洞,虫洞给出的形式为 A B C 代表能将你从 A 送到 B 点,并且回到 C 个 ...

  3. POJ 3259 Wormholes Bellman_ford负权回路

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

  4. POJ No 3259 Wormholes Bellman-Ford 判断是否存在负图

    题目:http://poj.org/problem?id=3259 题意:主要就是构造图, 然后判断,是否存在负图,可以回到原点 /* 2 3 3 1 //N, M, W 1 2 2 1 3 4 2 ...

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

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

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

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

  7. 最短路(Bellman_Ford) POJ 3259 Wormholes

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

  8. ACM: POJ 3259 Wormholes - SPFA负环判定

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

  9. poj - 3259 Wormholes (bellman-ford算法求最短路)

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

随机推荐

  1. rpm打包tomcat

    1.制作rpm包 yum install rpm-build -y 2.创建工作目录 mkdir -pv ~/rpmbuild/{BUILD,RPMS,SOURCES,SPECS,SRPMS} 3.准 ...

  2. Ant基础知识1

    1.Ant简介 Apache Ant是一个将软件编译/测试/部署等步骤联系在一起加以优化的一个构建工具,常用于java环境中的软件开发.Ant的默认配置文件是build.xml. 对java语言的支持 ...

  3. Multi-Nim游戏结论不变证明

    Nim取石子游戏结论: 若n堆石子的异或和为0,则先手必胜:否则,先手必败 加入新规则: 每次取完石子后,可以将取的那一堆的石子 分为多堆,也可以不分 结论: 同Nim取石子游戏结论 证明: 如果异或 ...

  4. 转 -- pydoc用法

    原文地址: https://www.cnblogs.com/meitian/p/6704488.html pydoc用法 pydoc是python自带的一个文档生成工具,使用pydoc可以很方便的查看 ...

  5. 01-VS充当IIS的配置步骤

    一. 背景 在实际开发中,经常会遇到需要在线调试,比如:第三方支付的回调.App接口借助PostMan工具测试,需要在代码上直接加断点,来进行调试,VS默认是不支持这种方式,需要手动配置一下,才能达到 ...

  6. 02-MySQL的安装和配置

    1. 软件和环境 注:安装MySQL数据库的操作系统必须保证有.NET环境和VC运行库的支持.    下载地址:百度云网盘链接 2. MySQL服务器安装详细步骤 (1). 选择安装类型 这里我们选择 ...

  7. Hibernate_day01

    一.今天内容介绍 1 web内容回顾 (1)javaee三层结构 (2)mvc思想 2 hibernate概述 3 hibernate入门案例 4 hibernate配置文件 5 hibernate的 ...

  8. 使用css将图像居中

    默认情况下,图像属于内联元素.这意味着它们与周围的文本一起流动.为使图像居中,我们应该将其转换成块级元素,通过将display属性的值设置为block就可以完成转换. <html> < ...

  9. spring整合ehcache2.5.2缓存异常-- net.sf.ehcache.CacheException

    报错如下: The source of the existing CacheManager is: DefaultConfigurationSource [ ehcache.xml or ehcach ...

  10. Jetson tk1 刷机后要做的几件事

    参考简书文章: http://www.jianshu.com/p/997ede860d74 1. 查看Jetson TK1 L4T版本 head -n 1 /etc/nv_tegra_release ...