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;
}
转载自北京大学暑期课课件