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