Wormholes( POJ 3259)(Bellman-Ford+SPFA)(判断是否有负权环)(最短路模板)

http://acm.hust.edu.cn/vjudge/problem/10533

Bellman-Ford
一共n个顶点,路径却经过了n条边,则必有一个顶点m经过了至少两次。则m是一个回路的起点和终点。走这个回路比不走这个回路路径更短,只能说明这个回路是负权回路。

#include <iostream>
#include <cstdio>
#include <string>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
#include <map>
#include <set>
#include <queue>

using namespace std;

int n, m, w;
const int INF = 1 << 30;

struct Edge
{
    int s, e, w;
    Edge(int ss, int ee, int ww) : s(ss), e(ee), w(ww) {}
    Edge() {}
};

vector<Edge> edges;
int dist[1000];

int Bellman_ford(int v)
{
    for (int i = 1; i<= n; i++) {
        dist[i] = INF;
    }
    dist[v] = 0;
    for (int k = 1; k < n; k++) {
        for (int i = 0; i < edges.size(); i++) {
            int s = edges[i].s;
            int e = edges[i].e;
            if (dist[s] + edges[i].w < dist[e]) {
                dist[e] = dist[s] + edges[i].w;
            }
        }
    }
    for (int i = 0; i < edges.size(); i++) {
        int s = edges[i].s;
        int e = edges[i].e;
        if (dist[s] + edges[i].w < dist[e]) return true;
    }
    return false;
}

int main()
{
    #ifndef ONLINE_JUDGE
    freopen ("in.txt", "r", stdin);
    #endif // ONLINE_JUDGE
    int t;
    scanf ("%d", &t);
    while (t--) {
        edges.clear();
        scanf ("%d%d%d", &n, &m, &w);
        for (int i = 0; i < m; i++) {
            int s, e, t;
            scanf ("%d%d%d", &s, &e, &t);
            edges.push_back(Edge (s, e, t));
            edges.push_back(Edge (e, s, t));
        }
        for (int i = 0; i < w; i++) {
            int s, e, t;
            scanf ("%d%d%d", &s, &e, &t);
            edges.push_back(Edge (s, e, -t));
        }
        if (Bellman_ford (1)) cout << "YES" << endl;
        else cout << "NO" << endl;
    }
    return 0;
}

SPFA

#include <iostream>
#include <cstdio>
#include <string>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
#include <map>
#include <set>
#include <queue>

using namespace std;
int n, m, w;
const int INF = 1 << 30;

struct Edge {
    int e, w;
    Edge (int ee, int ww) : e(ee), w(ww) {}
    Edge () {}
};

vector<Edge> G[1000];
int updateTimes[1000];
int dist[1000];

int spfa(int v)
{
    for (int i = 1; i <= n; i++) {
        dist[i] = INF;
    }
    dist[v] = 0;
    queue<int> que;
    que.push(v);
    memset (updateTimes, 0, sizeof(updateTimes));
    while (!que.empty()) {
        int s = que.front();
        que.pop();
        for (int i = 0; i < G[s].size(); i++) {
            int e = G[s][i].e;
            if (dist[e] > dist[s] + G[s][i].w) {
                dist[e] = dist[s] + G[s][i].w;
                que.push(e);
                ++updateTimes[e];
                if (updateTimes[e] >= n) return true;
            }
        }
    }
    return false;
}

int main()
{
    #ifndef ONLINE_JUDGE
    freopen ("in.txt", "r", stdin);
    #endif // ONLINE_JUDGE
    int t;
    scanf ("%d", &t);
    while (t--) {
        scanf ("%d%d%d", &n, &m, &w);
        for (int i = 1; i < 1000; i++) {
            G[i].clear();
        }
        int s, e, t;
        for (int i = 0; i < m; i++) {
            scanf ("%d%d%d", &s, &e, &t);
            G[s].push_back(Edge (e, t));
            G[e].push_back(Edge (s, t));
        }
        for (int i = 0; i < w; i++) {
            scanf ("%d%d%d", &s, &e, &t);
            G[s].push_back(Edge (e, -t));
        }
        if (spfa (1)) cout << "YES" << endl;
        else cout << "NO" << endl;
    }
    return 0;
}

转载自北京大学暑期课课件

    原文作者:Bellman - ford算法
    原文地址: https://blog.csdn.net/Ema1997/article/details/52280053
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞