判断是否存在负环

?





1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

#include <cstdio>

#include <cstdlib>

#include <cmath>

#include <map>

#include <set>

#include <queue>

#include <stack>

#include <vector>

#include <sstream>

#include <string>

#include <cstring>

#include <algorithm>

#include <iostream>

#define maxn 100010

#define INF 0x7fffffff

#define inf 100000000

#define MOD 1000000007

#define ULL unsigned long long

#define LL long long

using
namespace std;

struct
edge

{

    int
s, v, w;

}p[6100];

int
n, m, w, d[510], num_p;

void
addedge(int
a, int
b, int
c) {

    p[num_p].s = a;

    p[num_p].v = b;

    p[num_p].w = c;

    ++ num_p;

}

bool
bellom_form() {

    for(int
i = 1; i <= n; ++ i) {

        d[i] = inf;

    }

    d[1] = 0;

    for(int
i = 0; i < n-1; ++ i) {

        for(int
j = 0; j < num_p; ++ j) {

            if(d[p[j].v] > d[p[j].s]+p[j].w) {

                d[p[j].v] = d[p[j].s]+p[j].w;

            }

        }

    }

    for(int
i = 0; i < num_p; ++ i) {

        if(d[p[i].v] > d[p[i].s]+p[i].w) {

            return
true;

        }

    }

    return
false;

}

int
main()

{

    int
t;

    scanf("%d", &t);

    while(t --) {

        scanf("%d%d%d", &n, &m, &w);

        num_p = 0;

        for(int
i = 0; i < m; ++ i) {

            int
a, b, c;

            scanf("%d%d%d", &a, &b, &c);

            addedge(a, b, c);

            addedge(b, a, c);

        }

        for(int
i = 0; i < w; ++ i) {

            int
a, b, c;

            scanf("%d%d%d", &a, &b, &c);

            addedge(a, b, -c);

        }

        if(bellom_form()) puts("YES");

        else
puts("NO");

    }

    return
0;

}

  

判断是否存在负环,布布扣,bubuko.com

时间: 2024-10-06 11:24:27

判断是否存在负环的相关文章

vijos1053 用spfa判断是否存在负环

MARK 用spfa判断是否存在负环 判断是否存在负环的方法有很多, 其中用spfa判断的方法是:如果存在一个点入栈两次,那么就存在负环. 细节想想确实是这样,按理来说是不存在入栈两次的如果边权值为正的话 这个算法是O(N*M) 还有一种方法是直接用bellman-ford,虽说spfa也就是bellman-ford+FIFO队列 而且bellman-ford还可以计算负环的值 顺手附上代码好了: for(int i=0;i<n;i++) d[i]=INF;//初始化 d[0]=0; for(i

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

F - Wormholes Time Limit:2000MS    Memory Limit:65536KB    64bit IO Format:%I64d & %I64u SubmitStatus Description While exploring his many farms, Farmer John has discovered a number of amazing wormholes. A wormhole is very peculiar because it is a on

用SPFA判断是否存在负环

负环指的是权值和为负数的环,用SPFA加上DFS做比较方便,如果用BFS来做就要便利太多点了. 题目描述 暴力枚举/SPFA/Bellman-ford/奇怪的贪心/超神搜索 输入输出格式 输入格式: 第一行一个正整数T表示数据组数,对于每组数据: 第一行两个正整数N M,表示图有N个顶点,M条边 接下来M行,每行三个整数a b w,表示a->b有一条权值为w的边(若w<0则为单向,否则双向) 输出格式: 共T行.对于每组数据,存在负环则输出一行"YE5"(不含引号),否则输

poj 3259 Wormholes(bellman-ford判断负环)

题目链接:http://poj.org/problem?id=3259 题目就是问你能否回到原点而且时间还倒回去了.题目中有些路中有单向的虫洞能让时间回到过去 所以只要将虫洞这条边的权值赋为负然后再判断有没有负环就行了. #include <iostream> #include <cstring> using namespace std; const int inf = 10001; int f , n , m , w ,dis[1001] , counts; struct TnT

POJ-3259 Wormholes(判断负环、模板)

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! Eac

POJ Wormholes 最短路径 ballman_ ford 有负环

1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <iostream> 5 #include <queue> 6 #define MAX 9999999 7 8 using namespace std; 9 10 struct node 11 { 12 int u, v, w;//u 为起点,v为终点,w为u—>v的权值 13 }; 14 n

poj-3259-wormholes-spfa-判负环

题意:N个顶点, M条双向边, W条权值为负的单向边.求是否存在负环. 思路:首先你要懂bellman-ford或spfa..这是基础的spfa判断是否存在负环的题,存在负环的节点会重复入队(因为最短路在不断变小), 所以只要有节点重复入队超过n次,即可判断存在负环(即开一个数组记录节点入队次数). 总结:本来是想求出每对节点之间的最短路,看是否存在负的,结果果断TLE.后来才想起spfa可以处理负环云云~~ AC代码: 1 #include<iostream> 2 #include<c

POJ 3259 Wormholes 虫洞(负权最短路,负环)

题意:给一个混合图,求判断是否有负环的存在,若有,输出YES,否则NO.有重边. 思路:这是spfa的功能范围.一个点入队列超过n次就是有负环了.因为是混合图,所以当你跑一次spfa时发现没有负环,但是负环仍可能存在,因为有向边! 但是单源最短路也有起点啊,难道穷举起点?不用,负环是必须有某些边是带负权的,那么我们只要穷举负权边的起点就行了,因为单单跑一次spfa不能保证能遍历所有点,但是如果穷举负权边起点还没有找到负环,那么负环不可能存在(剩下的都是正权,怎么可能有负环). 1 //#incl

UVALive - 4618 Wormholes(负环)

题目大意:给出出发点和终点和m个虫洞(虫洞的出发点,终点,生成时间和花费时间),问从起点到终点花费的最小时间 解题思路:关键是有负环,所以直接跑最短路算法的话会TLE,所以负环要处理一下 但是这个负环又不是负环,因为负环到一定程度的话,就会消失. 比如,到达时间小于虫洞的生成时间,那么负环就消失了,也就是说,负环内的点满足的最优情况就是到达时间刚好等于生成时间 所以,先找出负环,接着判断一下这个负环内的能节省的最多时间,然后将所有点都减去那个时间,那么负环就消失了 具体看代码 #include