最大流
题目要求:给出n点 m边 src sink 然后每条边有 u v capacity 求最大流
EK(Edmonds–Karp)算法:
| #include <iostream> |
| #include <vector> |
| #include <queue> |
| #include <algorithm> |
| #include <cstring> |
| #include <cstdio> |
| #define int long long |
| const int N = 6e5 + 9; |
| const int inf2 = 0x7f7f7f7f; |
| |
| using namespace std; |
| #define int long long |
| #define ios std::ios::sync_with_stdio(false); std::cin.tie(0); |
| |
| int n, m, src, sink; |
| int ans = 0; |
| int head[N]; |
| int pre[N]; |
| struct node { |
| int to, capacity, next; |
| } e[N]; |
| bool vis[N]; |
| int idx = 1; |
| int dist[N]; |
| int flag[2510][2510]; |
| |
| void add(int u, int v, int val) { |
| |
| e[++idx] = {v, val, head[u]}; |
| head[u] = idx; |
| |
| e[++idx] = {u, 0, head[v]}; |
| head[v] = idx; |
| } |
| |
| bool bfs() { |
| memset(vis, 0, sizeof vis); |
| dist[src] = inf2; |
| queue<int> q; |
| q.push(src); |
| vis[src] = 1; |
| |
| while (!q.empty()) { |
| int u = q.front(); |
| q.pop(); |
| for (int i = head[u]; i != 0; i = e[i].next) { |
| int v = e[i].to; |
| int val = e[i].capacity; |
| |
| if (e[i].capacity == 0 || vis[v]) continue; |
| vis[v] = 1; |
| pre[v] = i; |
| dist[v] = min(dist[u], val); |
| q.push(v); |
| if (v == sink) |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| void EK() { |
| int u = sink; |
| while (u != src) { |
| int mmin_stream = dist[sink]; |
| int last = pre[u]; |
| |
| e[last].capacity -= mmin_stream; |
| e[last ^ 1].capacity += mmin_stream; |
| u = e[last ^ 1].to; |
| } |
| ans += dist[sink]; |
| } |
| |
| void bd() { |
| cin >> n >> m >> src >> sink; |
| for (int i = 1; i <= m; ++i) { |
| int u, v, val; |
| cin >> u >> v >> val; |
| if (flag[u][v] == 0) { |
| add(u, v, val); |
| flag[u][v] = idx - 1; |
| } |
| else |
| e[flag[u][v]].capacity += val; |
| |
| } |
| } |
| |
| signed main() { |
| ios; |
| bd(); |
| while (bfs()) { |
| EK(); |
| } |
| cout << ans; |
| return 0; |
| } |
| |
Dinic算法
思路
| #include <iostream> |
| #include <vector> |
| #include <queue> |
| #include <algorithm> |
| #include <climits> |
| |
| using namespace std; |
| #define int long long |
| const int inf = 2005020600; |
| const int N = 2e6 + 9; |
| |
| int m, src, sink, n; |
| int ans, dist[N]; |
| int idx = 1, now[N], head[N]; |
| |
| struct node { |
| int to, next; |
| int capacity; |
| } e[N]; |
| |
| void add(int u, int v, int val) { |
| |
| e[++idx] = {v, head[u], val}; |
| head[u] = idx; |
| |
| |
| e[++idx] = {u, head[v], 0}; |
| head[v] = idx; |
| } |
| |
| int bfs() { |
| fill(dist, dist + n + 1, inf); |
| |
| queue<int> q; |
| q.push(src); |
| dist[src] = 0; |
| now[src] = head[src]; |
| |
| while (!q.empty()) { |
| int x = q.front(); |
| q.pop(); |
| for (int i = head[x]; i!=0; i = e[i].next) { |
| int v = e[i].to; |
| if (e[i].capacity > 0 && dist[v] == inf) { |
| q.push(v); |
| now[v] = head[v]; |
| dist[v] = dist[x] + 1; |
| if (v == sink) |
| return true; |
| } |
| } |
| } |
| return false; |
| } |
| |
| int dfs(int x, int sum) { |
| if (x == sink) return sum; |
| |
| int k, res = 0; |
| for (int i = now[x]; i && sum; i = e[i].next) { |
| now[x] = i; |
| int v = e[i].to; |
| if (e[i].capacity > 0 && (dist[v] == dist[x] + 1)) { |
| k = dfs(v, min(sum, e[i].capacity)); |
| if (k == 0) dist[v] = inf; |
| e[i].capacity -= k; |
| e[i ^ 1].capacity += k; |
| res += k; |
| sum -= k; |
| } |
| } |
| return res; |
| } |
| int dinic(){ |
| while (bfs()) { |
| ans += dfs(src, inf); |
| } |
| return ans; |
| } |
| signed main() { |
| cin >> n >> m >> src >> sink; |
| for (int i = 1; i <= m; i++) { |
| int u, v; |
| int val; |
| cin >> u >> v >> val; |
| add(u, v, val); |
| } |
| cout <<dinic(); |
| return 0; |
| } |
| |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· .NET10 - 预览版1新功能体验(一)