Pagini recente » Cod sursa (job #496882) | Cod sursa (job #2770900) | Cod sursa (job #2778527) | tema | Cod sursa (job #2781616)
#include <bits/stdc++.h>
using namespace std;
template<typename T>
class MaxFlow{
private:
int n, m;
T f = 0;
vector<vector<int>> adj;
vector<vector<T>> capacity;
vector<vector<T>> dual;
vector<bool> visited;
vector<int> prev;
vector<int> path;
public:
void Init(int n){
this->n = n;
adj = vector<vector<int>> (n + 1);
capacity = vector<vector<T>> (n + 1, vector<T>(n + 1));
dual = vector<vector<T>> (n + 1, vector<T>(n + 1, 0));
visited = vector<bool> (n + 1, false);
prev = vector<int> (n + 1, - 1);
}
void addEdge(int i, int j, T c){
m++;
adj[i].push_back(j);
adj[j].push_back(i);
capacity[i][j] = c;
dual[i][j] += c;
}
void DFS(int v, int t, vector<int>& path, bool& check){
if(check)
return;
visited[v] = true;
if(t == v){
check = true;
int l = path.size();
T M = dual[path[0]][path[1]];
for(int i = 0; i < l - 1; i++)
M = min(M, dual[path[i]][path[i + 1]]);
for(int i = 0; i < l - 1; i++){
dual[path[i]][path[i + 1]] -= M;
dual[path[i + 1]][path[i]] += M;
}
f += M;
return;
}
for(auto u : adj[v])
if(!visited[u] && dual[v][u] > 0){
path.push_back(u);
DFS(u, t, path, check);
path.pop_back();
}
}
T computeFlowDFS(int s, int t){
bool check = true;
while(check){
check = false;
path.clear();
path.push_back(s);
for(int i = 0; i <= n; i++)
visited[i] = false;
DFS(s, t, path, check);
}
return f;
}
T computeFlowBFS(int s, int t){
bool check = false;
while(!check) {
check = true;
queue<int> q;
q.push(s);
for(int i = 0; i <= n; i++)
prev[i] = -1;
while (!q.empty() && prev[t] == -1) {
int v = q.front();
q.pop();
for(auto u : adj[v])
if(dual[v][u] > 0 && prev[u] == -1){
q.push(u);
prev[u] = v;
}
}
if(prev[t] != -1) {
check = false;
T M = 1e9;
int v = t;
while (v != s) {
M = min(M, dual[prev[v]][v]);
v = prev[v];
}
v = t;
while (v != s) {
dual[prev[v]][v] -= M;
dual[v][prev[v]] += M;
v = prev[v];
}
f += M;
}
}
return f;
}
};
int main() {
freopen("maxflow.in", "r", stdin);
freopen("maxflow.out", "w", stdout);
MaxFlow<int> f;
int n, m;
cin >> n >> m;
f.Init(n);
for(int i = 0; i < m; i++){
int a, b, c;
cin >> a >> b >> c;
f.addEdge(a, b, c);
}
cout << f.computeFlowBFS(1, n);
return 0;
}