Online JudgeProblem SetAuthorsOnline ContestsUser
Web Board
Home Page
F.A.Qs
Statistical Charts
Problems
Submit Problem
Online Status
Prob.ID:
Register
Update your info
Authors ranklist
Current Contest
Past Contests
Scheduled Contests
Award Contest
User ID:
Password:
  Register

SPFA faster than Bellman-Ford: [C++] Code

Posted by __ea at 2016-11-27 10:10:17 on Problem 3621
/*
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:
User ID:
Password:
Title:

Content:

Home Page   Go Back  To top


All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator