SPFA 全称 Shortest Path Faster Algorithm
基本应用为快速求解单源最短路
用该算法判断图中是否存在负权环(POJ3259):若一个点最短路被改进的次数达到n,则有负权环
#include <iostream>
#include <vector>
#include <queue>
#include <cstring>
using namespace std;
int F,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()
{
cin >> F;
while( F--) {
cin >> N >> M >> W;
for( int i = 1; i <1000; ++i)
G[i].clear();
for( int i = 0; i < M; ++ i) {
int s,e,t;
cin >> s >> e >> t;
G[s].push_back(Edge(e,t));
G[e].push_back(Edge(s,t));
}
for( int i = 0;i < W; ++i) {
int s,e,t;
cin >> s >> e >> t;
G[s].push_back(Edge(e,-t));
}
if( Spfa(1))
cout << "YES" <<endl;
else
cout << "NO" <<endl;
}
}