Pagini recente » Cod sursa (job #3176420) | Cod sursa (job #1306646) | Cod sursa (job #1845720) | Cod sursa (job #1444738) | Cod sursa (job #2967784)
//#include <bits/stdc++.h>
#include <iostream>
#include <fstream>
#include <vector>
#include <cmath>
#include <climits>
#include <queue>
using namespace std;
const int MAX = 1e6;
#define ll long long
ifstream fin("maxflow.in");
ofstream fout("maxflow.out");
//vector <vector<int>> capacitate;
//
//int path[MAX];
//bool vizitat[MAX];
//
//int M, N;
//ll pathLength;
/// ======================== Bellmanford O(V * E^2)
/// https://www.youtube.com/watch?v=LdOnanfc5TM&list=PLDV1Zeh2NRsDGO4--qE8yH72HFL1Km93P&index=33
// DFS, BFS, DIJKSTRA
//int getPath(int startNode, int targetNode, int curLen, int maxCap) {
// path[curLen] = startNode;
//
// if (startNode == targetNode) {
// pathLength = curLen + 1;
// return maxCap;
// }
//
// int res = 0;
// vizitat[startNode] = true;
//
// for (int i = 0; i < N; ++i) {
// if (vizitat[i] || capacitate[startNode][i] <= 0) continue;
// res = getPath(i, targetNode, curLen + 1, min(maxCap, capacitate[startNode][i]));
// if (res > 0) break;
// }
//
// return res;
//}
//
//ll maxFlow(int startNode, int endNode) {
// ll totalFlow = 0;
//
// while (true) {
// memset(vizitat, false, sizeof (vizitat));
// int newFlow = getPath(startNode, endNode, 0, INT_MAX);
//
// if (newFlow <= 0)break; // once there is no paths anymore stop the algo
//
// for (int i = 1; i < pathLength; ++i) {
// int m = path[i - 1];
// int n = path[i];
// capacitate[m][n] -= newFlow;
// capacitate[n][m] += newFlow;
// }
// totalFlow += newFlow;
// }
//
// return totalFlow;
//}
/// ======================== Capacity Scaling O(E^2 * Log(U)) or O(E * V Log(U)) if SHORTEST PATH
// U = MAX Value ( Capacities)
// delta = smallest power of 2 less than or equal to U.
// https://www.youtube.com/watch?v=1ewLrXUz4kk&list=PLDV1Zeh2NRsDGO4--qE8yH72HFL1Km93P&index=40
// repeatedly delta = delta / 2
vector<vector<int>> capacity;
vector<vector<int>> graph;
vector<bool> visited;
vector<int> parent;
int remainingCapacity = 0;
int M, N;
/// TLE
//ll dfs(int s, int t, int flow) {
//
//
// if (s == t) return flow;
//
// visited[s] = true;
// for (int i = 0; i < capacity[s].size(); ++i) {
// int cap = capacity[s][i];
// if (cap >= delta && !visited[i]) {
// parent[i] = s;
// ll bottleNeck = dfs(i, t, min(cap, flow));
// if (bottleNeck > 0) {
// return bottleNeck;
// }
// }
//
// }
//
//
// return 0;
//}
// OPTIMIZARATA
bool bfs(int s, int t) {
fill(visited.begin(), visited.end(), false);
queue<int> q;
q.push(s);
visited[s] = true;
parent[s] = -1;
while (!q.empty()) {
int u = q.front();
q.pop();
// cout << "while BFS " <<endl;
for (auto v: graph[u]) {
int weight = capacity[u][v];
if (!visited[v] && weight != 0) {
parent[v] = u;
if (v == t)
return true;
visited[v] = true;
q.push(v);
}
}
}
return false;
}
//4 5
//1 2 3
//1 3 5
//2 4 6
//3 4 4
//3 2 3
ll maxFlow(int s, int t) {
ll flow = 0;
int newFlow = INT_MAX;
bool result = false;
do {
result = bfs(s, t);
for (int v = t; v != s; v = parent[v]) {
int u = parent[v];
newFlow = min(newFlow, capacity[u][v]);
}
for (int v = t; v != s; v = parent[v]) {
int u = parent[v];
capacity[u][v] -= newFlow;
capacity[v][u] += newFlow;
}
flow += newFlow;
} while (result);
return flow;
}
//4 5
//1 2 3
//1 3 5
//2 4 6
//3 4 4
//3 2 3
int main() {
// fin >> N >> M;
//
// capacity.resize(N + 1, vector<int>(N + 1));
//
// graph.resize(N + 1);
// parent.resize(N + 1);
// visited.resize(N + 1);
//
// for (int i = 0; i < M; ++i) {
// int x, y;
// int z;
// fin >> x >> y >> z;
// graph[x].push_back(y);
// graph[y].push_back(x);
// capacity[x][y] = z;
// }
//
// fout << maxFlow(1, N);
//
cin >> N >> M;
capacity.resize(N + 1, vector<int>(N + 1));
graph.resize(N + 1);
parent.resize(N + 1);
visited.resize(N + 1);
for (int i = 0; i < M; ++i) {
int x, y;
int z;
cin >> x >> y >> z;
graph[x].push_back(y);
graph[y].push_back(x);
capacity[x][y] = z;
}
cout << maxFlow(1, N);
return 0;
}