| ||||||||||
| Online Judge | Problem Set | Authors | Online Contests | User | ||||||
|---|---|---|---|---|---|---|---|---|---|---|
| Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest | |||||||||
SPFA faster than Bellman-Ford: [C++] Code/*
ID:
PROG:
LANG: C++
*/
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
#include <cctype>
#include <stack>
#include <queue>
#include <list>
#include <vector>
#include <map>
#include <sstream>
#include <cmath>
#include <bitset>
#include <utility>
#include <set>
#include <numeric>
#include <climits>
#include <cstdlib>
using namespace std;
const double Pi=acos(-1.0);
typedef long long LL;
#define Set(a, s) memset(a, s, sizeof (a))
#define Rd(r) freopen(r, "r", stdin)
#define Wt(w) freopen(w, "w", stdout)
#define MAX_V 1001
#define MAX_E 5001
// Decides whether to use SPFA or not
const bool SPFA = true;
pair<pair<int, int>, int> edgelist[MAX_E];
vector<int> graph[MAX_V];
int adj[MAX_V][MAX_V], fun[MAX_V], V, E;
// O(nm) single source, works on negative weight edges, return false iff there is a negative weight cycle
bool bellmanford(double cap) {
static double tdist[MAX_V];
Set(tdist, 0);
for (int i = 0; i < V - 1; i++) {
for (int j = 0; j < E; j++) {
int a = edgelist[j].first.first;
int b = edgelist[j].first.second;
int d = edgelist[j].second;
// relax edge
tdist[b] = max(tdist[b], tdist[a] + fun[b]-cap*d);
}
}
for (int i = 0; i < E; i++) {
int a = edgelist[i].first.first;
int b = edgelist[i].first.second;
int d = edgelist[i].second;
// relax edge
if (tdist[a] + fun[b]-cap*d > tdist[b])
return false;
}
return true;
}
bool spfa(double cap) {
static int cnt[MAX_V];
static double tdist[MAX_V];
static bool in_que[MAX_V];
static queue<int> q;
Set(cnt, 0);
Set(tdist, 0);
Set(in_que, 1);
while(q.size()) q.pop();
for (int i = 1; i <= V; i++) q.push(i);
while(q.size()) {
int curr = q.front(); q.pop();
in_que[curr] = false;
for (int i = 0; i < graph[curr].size(); i++) {
int nxt = graph[curr][i];
double w = fun[nxt] - cap*adj[curr][nxt];
if (tdist[curr] + w > tdist[nxt]) {
tdist[nxt] = tdist[curr]+w;
if (++cnt[nxt] >= V)
return false;
if (!in_que[nxt]) {
in_que[nxt] = true;
q.push(nxt);
}
}
}
}
return true;
}
int main ()
{
scanf("%d", &V);
scanf("%d", &E);
for (int i = 1; i <= V; i++)
scanf("%d", &fun[i]);
for (int i = 0; i < E; i++) {
if (!SPFA) {
scanf("%d", &edgelist[i].first.first);
scanf("%d", &edgelist[i].first.second);
scanf("%d", &edgelist[i].second);
} else {
int nodeA, nodeB, len;
scanf("%d", &nodeA);
scanf("%d", &nodeB);
scanf("%d", &len);
adj[nodeA][nodeB] = min(adj[nodeA][nodeB], len);
if (!adj[nodeA][nodeB]) {
graph[nodeA].push_back(nodeB);
adj[nodeA][nodeB] = len;
}
}
}
double high = 1000, low = 0;
while (high - low > 1e-4) {
double mid = (high+low) / 2;
if (SPFA)
spfa(mid) ? high=mid : low=mid;
else
bellmanford(mid) ? high=mid : low=mid;
}
printf("%0.2f", high);
return 0;
}
Followed by: Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator