我一直在尝试使用Dinic算法和C ++在Spoj上解决Fastflow,但是我一直在获得TLE。我想知道是否有什么方法可以改善我的代码,使其不超过时间限制,或者算法是否不够快地完成该任务?我正在使用BFS查找每个节点与源节点的距离,然后使用DFS查找可以从源向接收器发送多少流量。
#include <iostream>
#include <cmath>
#include <vector>
#include <algorithm>
#include <queue>
#include <cstring>
using namespace std;
struct Edge {
int from, to, flow, capacity;
Edge *reverse;
};
static vector<vector<Edge>> nodeEdges(5002, vector<Edge>());
int source, sink, nodes, level[5002];
void add(int u, int v, int c) {
Edge e1{ u, v, 0, c };
Edge e2{ v, u, 0, c };
e1.reverse = &e2;
e2.reverse = &e1;
nodeEdges[u].push_back(e1);
nodeEdges[v].push_back(e2);
}
bool bfs() {
int s, t, u, v;
memset(level, -1, sizeof(int)*(nodes+1));
level[source] = 0;
s = 0;
t = 0;
queue<int> q;
q.push(source);
while (!q.empty()) {
u = q.front();
q.pop();
for (int i = 0; i < nodeEdges[u].size(); i++) {
v = nodeEdges[u][i].to;
if (nodeEdges[u][i].flow < nodeEdges[u][i].capacity && level[v] == -1) {
level[v] = level[u] + 1;
q.push(v);
}
}
}
if (level[sink] == -1) {
return false;
}
return true;
}
long long dfs(int u, int fl) {
if (u == sink) return fl;
int v;
long long pushed;
for (int i = 0; i < nodeEdges[u].size(); i++) {
v = nodeEdges[u][i].to;
if (nodeEdges[u][i].flow < nodeEdges[u][i].capacity && level[v] == level[u] + 1) {
pushed = dfs(v, min(nodeEdges[u][i].capacity - nodeEdges[u][i].flow, fl));
if (pushed > 0) {
nodeEdges[u][i].flow += pushed;
nodeEdges[u][i].reverse->flow -= pushed;
return pushed;
}
}
}
return 0;
}
long long solve() {
long long ret = 0;
long long flow;
while (bfs()) {
while (true) {
flow = dfs(source, INT32_MAX);
if (flow) {
ret += flow;
}
else break;
}
}
return ret;
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int n, m, a, b, c;
cin >> n >> m;
source = 1;
sink = n;
nodes = n;
for (int i = 0; i < m; i++) {
cin >> a >> b >> c;
if (a != b) {
add(a, b, c);
}
}
cout << solve();
return 0;
}
答案 0 :(得分:1)
您添加边缘的reverse
指针均无效,因为它们指向add
局部变量。他们需要指向被添加到nodeEdges[u]
(或nodeEdges[v]
)中的节点 。