-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsolution.cpp
More file actions
139 lines (109 loc) · 4.16 KB
/
Copy pathsolution.cpp
File metadata and controls
139 lines (109 loc) · 4.16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#include<bits/stdc++.h>
using namespace std;
#define int long long
class Dinic {
public:
struct Edge {
int to, rev;
int flow, cap;
};
Dinic(int n) : graph(n), level(n), start(n) {}
void addEdge(int u, int v, int cap) {
graph[u].push_back({v, static_cast<int>(graph[v].size()), 0, cap});
graph[v].push_back({u, static_cast<int>(graph[u].size()) - 1, 0, 0}); // reverse edge
}
int maxFlow(int s, int t) {
int total_flow = 0;
while (bfs(s, t)) {
std::fill(start.begin(), start.end(), 0);
while (int flow = dfs(s, t, INT_MAX)) {
total_flow += flow;
}
}
return total_flow;
}
private:
std::vector<std::vector<Edge>> graph;
std::vector<int> level, start;
bool bfs(int s, int t) {
std::fill(level.begin(), level.end(), -1);
level[s] = 0;
std::queue<int> q;
q.push(s);
while (!q.empty()) {
int u = q.front();
q.pop();
for (const Edge &e : graph[u]) {
if (level[e.to] < 0 && e.flow < e.cap) {
level[e.to] = level[u] + 1;
q.push(e.to);
}
}
}
return level[t] >= 0;
}
int dfs(int u, int t, int flow) {
if (u == t) return flow;
for (int &i = start[u]; i < graph[u].size(); ++i) {
Edge &e = graph[u][i];
if (level[e.to] == level[u] + 1 && e.flow < e.cap) {
int curr_flow = std::min(flow, e.cap - e.flow);
int temp_flow = dfs(e.to, t, curr_flow);
if (temp_flow > 0) {
e.flow += temp_flow;
graph[e.to][e.rev].flow -= temp_flow;
return temp_flow;
}
}
}
return 0;
}
};
/*
### Explanation
- **Graph Representation**: The graph is represented using adjacency lists, where each node has a list of edges. Each edge contains the destination node, the reverse edge index, the current flow, and the capacity.
- **BFS**: Used to build the level graph, which helps in finding augmenting paths more efficiently.
- **DFS**: Used to find blocking flows along the level graph.
- **Flow Augmentation**: Flow is augmented along the path found by DFS, and both forward and reverse edges are updated.
### Guiding Question
What would you do if the graph had very large capacities that might cause integer overflow? How would you modify the implementation to handle such cases?
### Next Learning Objective
Understand how to handle large input sizes and capacities in flow algorithms, ensuring robustness against overflow.
*/
void solve() {
int n, m;
cin >> n >> m;
// Coach: Create a Dinic object with n+2 number of node
/* [Coach Response]
To create a Dinic object with `n+2` nodes, you need to instantiate the Dinic class with `n+2` as the parameter. This is often done to include additional nodes such as a super-source and super-sink in flow network problems.
Here's the exact line to create the Dinic object with `n+2` nodes:
*/
Dinic dinic(n + 2);
/* [Coach Response]
### Implementation in Context
Here's how you can use this line in your `solve` function:
*/
void solve() {
int n, m;
cin >> n >> m;
// Create a Dinic object with n+2 nodes
Dinic dinic(n + 2);
// Further implementation for adding edges and calculating max flow
}
/* [Coach Response]
### Explanation
- **`n+2` Nodes**: This setup accounts for the original `n` nodes plus two additional nodes. These extra nodes are often used as a super-source and a super-sink, which can simplify handling multiple sources or sinks in the network.
- **Dinic Initialization**: `Dinic dinic(n + 2);` initializes the graph data structures within the Dinic class to accommodate `n+2` nodes, preparing it for subsequent operations like adding edges and calculating flows.
Why might you want to use a super-source or super-sink in a flow network problem, and how do they simplify the problem?
*/
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t = 1;
cin >> t;
while (t--) {
solve();
}
return 0;
}