table of Contents
Wormholes (SPFA negative determination ring)
Topic poj3259
Subject to the effect
Given F farm, i.e. N sets of samples. Each sample is given n, m, w are the points, the number of edges (two-way, will consume time elapsed t), the number of wormholes (unidirectional, returns after a time t).
If he can return to a certain point and time than before to reach this point is smaller, then the output "YES" Otherwise, output "NO".
Thinking
If an ordinary way, then the time counts as a positive, if a wormhole counts as negative. Then run spfa.
In spfa, if the number of times through the point (i.e. the number of enqueued point) exceeds n, then that there is a negative loop, the output yes, return. If the queue is empty, outputs NO
#include <iostream>
#include <vector>
#include <queue>
#define N 1000
#define E 3000
#define INF 0x3f3f3f
using namespace std;
vector<pair<int, int>> eg[N];
queue<int> q;
int inq[N];
int d[N];
int n, m, w;
void init()
{
for (int i = 0; i <= n; i++)
inq[i] = 0;
for (int i = 0; i <= n; i++)
eg[i].clear();
for (int i = 0; i <= n; i++)
d[i] = INF;
}
void spfa()
{
q.push(0);
inq[0]++;
d[0] = 0;
while (!q.empty())
{
int now = q.front();
q.pop();
for (int i = 0; i < eg[now].size(); i++)
{
int v = eg[now][i].first;
if (d[v] > d[now] + eg[now][i].second)
{
d[v] = d[now] + eg[now][i].second;
//cout << now << " " << v << " " << d[v] << endl;
if (inq[v] > n)
{
cout << "YES" << endl;
return;
}
else
{
inq[v]++;
q.push(v);
}
}
}
}
cout << "NO" << endl;
}
int main()
{
int T, s, e, t;
cin >> T;
while (T--)
{
cin >> n >> m >> w;
init();
for (int i = 1; i <= m; i++)
{
cin >> s >> e >> t;
s--, e--;
eg[s].push_back(make_pair(e, t));
eg[e].push_back(make_pair(s, t));
}
for (int i = 1; i <= w; i++)
{
cin >> s >> e >> t;
s--, e--;
eg[s].push_back(make_pair(e, -t));
}
spfa();
}
}