Pagini recente » Cod sursa (job #1711554) | Monitorul de evaluare | Cod sursa (job #1375698) | Monitorul de evaluare | Cod sursa (job #3329684)
#include <bits/stdc++.h>
using namespace std;
ifstream fin("maxflow.in");
ofstream fout("maxflow.out");
const int INF = 2e9;
int n, m, maxflow;
vector<int> vis, parent;
vector<vector<int>> adj_list;
vector<vector<int>> cap, flow;
void read()
{
// read input data
fin >> n >> m;
adj_list.assign(n + 5, {});
cap.assign(n + 5, vector<int>(n + 5, 0));
flow.assign(n + 5, vector<int>(n + 5, 0));
vis.assign(n + 5, 0);
parent.assign(n + 5, 0);
for (int i = 0; i < m; i++)
{
int x, y, capacity;
fin >> x >> y >> capacity;
adj_list[x].push_back(y);
adj_list[y].push_back(x);
cap[x][y] = capacity;
}
}
bool find_paths()
{
// try to find augumenting paths from source to sink
for (int i = 0; i <= n; i++)
vis[i] = 0;
queue<int> Q;
Q.push(1);
vis[1] = 1;
while (!Q.empty())
{
int curr = Q.front();
Q.pop();
for (auto &next : adj_list[curr])
{
if (!vis[next] && cap[curr][next] > flow[curr][next])
{
parent[next] = curr;
vis[next] = 1;
Q.push(next);
if (next == n)
return true;
}
}
}
return false; // no path found
}
void solve()
{
// ford-fulkerson (edmonds-karp)
while (find_paths())
{
// traverse found paths from leafs connected to sink
for (auto leaf : adj_list[n])
{
if (vis[leaf] && cap[leaf][n] > flow[leaf][n])
{
// find bottleneck val
parent[n] = leaf;
int bottleneck = INF;
int temp = n;
while (parent[temp])
{
bottleneck = min(bottleneck, cap[parent[temp]][temp] - flow[parent[temp]][temp]);
temp = parent[temp];
}
maxflow += bottleneck; // maxflow = sum of bottleneck values
// augument the path with bottleneck val
temp = n;
while (parent[temp])
{
// update flows
flow[parent[temp]][temp] += bottleneck;
flow[temp][parent[temp]] -= bottleneck;
temp = parent[temp];
}
}
}
}
fout << maxflow;
}
int main()
{
read();
solve();
return 0;
}