问题思考:
- 问空间站的容量应该是多少,可以等价于最大流问题。即空间站的容量应该等于网络的最大流。
参考视频:
代码实现:
- 我用GPT帮我写了一段 Dinic's Algorithm 寻找网络最大流的C++代码。改了一下输入输出,和空间站 id 的映射,提交发现测试节点 3 出现段错误:
- 又让他给出改进的建议:函数递归层数太深,导致程序内存函数栈爆满,采用非递归方式避免了不断调用函数的问题,提交就直接过了。
以下是完整代码:
#include <bits/stdc++.h>
using namespace std;
const int INF = 1e9;
struct Edge {
int from, to, capacity, flow;
};
class Dinic {
public:
int nodes, src, sink;
vector<Edge> edges;
vector<vector<int>> adj;
vector<int> level, ptr;
Dinic(int n, int s, int t) : nodes(n), src(s), sink(t), adj(n), level(n, -1), ptr(n) {}
void addEdge(int from, int to, int capacity) {
edges.push_back({from, to, capacity, 0});
edges.push_back({to, from, 0, 0});
adj[from].push_back(edges.size() - 2);
adj[to].push_back(edges.size() - 1);
}
bool bfs() {
fill(level.begin(), level.end(), -1);
level[src] = 0;
queue<int> q;
q.push(src);
while (!q.empty()) {
int current = q.front();
q.pop();
for (int id : adj[current]) {
if (edges[id].capacity - edges[id].flow > 0 && level[edges[id].to] == -1) {
level[edges[id].to] = level[current] + 1;
q.push(edges[id].to);
}
}
}
return level[sink] != -1;
}
int dfs(int u, int pushed) {
stack<pair<int, int>> stk;
stk.push({u, pushed});
while (!stk.empty()) {
int u = stk.top().first;
int pushed = stk.top().second;
stk.pop();
if (pushed == 0) continue;
if (u == sink) return pushed;
for (int& cid = ptr[u]; cid < adj[u].size(); cid++) {
int id = adj[u][cid];
int v = edges[id].to;
if (level[u] + 1 == level[v] && edges[id].capacity - edges[id].flow > 0) {
int flow = min(pushed, edges[id].capacity - edges[id].flow);
int pushed_flow = dfs(v, flow);
if (pushed_flow > 0) {
edges[id].flow += pushed_flow;
edges[id ^ 1].flow -= pushed_flow;
return pushed_flow;
}
}
}
}
return 0;
}
int maxFlow() {
int flow = 0;
while (bfs()) {
fill(ptr.begin(), ptr.end(), 0);
while (int pushed = dfs(src, INF)) {
flow += pushed;
}
}
return flow;
}
};
int main() {
int nodes;
string src, sink;
cin >> src >> sink >> nodes;
// Note: You might need to adjust the maximum size of the nodes.
const int MAX_NODES = 10005;
unordered_map<string, int> M;
int cnt = 0;
auto mark_to_map = [&](string id) {
if (M.find(id) == M.end())
M[id] = ++cnt;
};
mark_to_map(src);
mark_to_map(sink);
Dinic dinic(MAX_NODES, M[src], M[sink]);
for (int i = 0; i < nodes; i++) {
string a, b;
int l;
cin >> a >> b >> l;
mark_to_map(a);
mark_to_map(b);
dinic.addEdge(M[a], M[b], l);
}
int maxFlow = dinic.maxFlow();
cout << maxFlow << endl;
return 0;
}