#include<iostream>
#include<fstream>
using namespace std;
struct Edge
{
int s;
int e;
int t;
};
static const int MAX = 30000;
static const int MAXEDGES = 6000; /* caution */
static const int MAXNODES = 501;
static int n, m, w;
struct Edge edges[MAXEDGES];
static int dist[MAXNODES];
//#define DEBUG
int bellman_ford(void)
{
int edgenum = m + m + w; /* edges */
int i, j;
for (i = 1; i <= n; i++)
{
dist[i] = MAX;
}
dist[1] = 0;
for (i = 1; i < n; i++) /* Relax all edges |v|-1 times */
{
int ok = 1; /* reduce about 80ms */
for (j = 0; j < edgenum; j++)
{
int s, e, t;
s = edges[j].s; e = edges[j].e; t = edges[j].t;
if (dist[s] + t < dist[e])
{ dist[e] = dist[s] + t; ok = 0; }
}
if (ok)
break;
}
for (j = 0; j < edgenum; j++) /* check minus loop */
{
int s, e, t;
s = edges[j].s; e = edges[j].e; t = edges[j].t;
if (dist[s] + t < dist[e])
return 0;
}
return 1;
}
int main()
{
#ifdef DEBUG
fstream cin("G:\\book\\algorithms\\acm\\Debug\\dat.txt");
#endif
int fields;
cin >> fields;
while (fields-- >0)
{
cin >> n >> m >> w;
int i, k = 0;
int s, e, t;
for (i = 0; i < m; i++)
{
cin >> s >> e >>t;
edges[k].s = s;
edges[k].e = e;
edges[k++].t = t;
edges[k].s = e;
edges[k].e = s;
edges[k++].t = t;
}
for (i = 0; i < w; i++)
{
cin >> s >> e >>t;
edges[k].s = s;
edges[k].e = e;
edges[k++].t = -t; /* minus weigh edge */
}
if (!bellman_ford())
cout << "YES" << endl;
else
cout << "NO" << endl;
}
return 0;
}
算法的正确性见 算法导论 24.1节相关内容。
存在负权回路,负权回路上的顶点可以进行无限制的松弛。
存在负权路径无法进行最短路径的计算见 算法导论 图24 -1即可明白。
代码中加注释的地方,都曾经出现过错误,注意。