Cod sursa(job #2475687)

Utilizator Cristian1997Vintur Cristian Cristian1997 Data 17 octombrie 2019 12:51:24
Problema Flux maxim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.19 kb
#include <bits/stdc++.h>
using namespace std;
using uint = unsigned int;
using ll = long long;
using ull = unsigned long long;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
#define dbg(x) cerr<<#x": "<<(x)<<endl
#define dbg_p(x) cerr<<#x": "<<(x).first<<' '<<(x).second<<endl
#define dbg_v(x, n) {cerr<<#x"[]: ";for(long long _=0;_<n;++_)cerr<<(x)[_]<<' ';cerr<<endl;}
#define all(v) v.begin(), v.end()
#define fi first
#define se second

template<typename T1, typename T2>
ostream& operator <<(ostream &out, const pair<T1, T2> &item) {
	out << '(' << item.first << ", " << item.second << ')';
	return out;
}

template <typename T>
ostream& operator <<(ostream &out, const vector<T>& v) {
	for(const auto &item : v) out << item << ' ';
	return out;
}

const int N = 1010;
const int INF = 0x3f3f3f3f;

struct Edge {
	int to, flow;
};

int source, sink;
int d[N], ptr[N];
vector<int> adj[N];
vector<Edge> edges;

void addEdge(int a, int b, int cap) {
	adj[a].push_back(edges.size());
	edges.push_back({b, cap});
	
	adj[b].push_back(edges.size());
	edges.push_back({a, 0});
}

bool bfs(int v) {
	queue<int> q;
	memset(d, INF, sizeof d);
	
	for(q.push(v), d[v] = 0; !q.empty(); q.pop()) {
		for(auto id : adj[v = q.front()]) {
			int u = edges[id].to;
			if(edges[id].flow && d[u] > d[v] + 1) {
				d[u] = d[v] + 1;
				q.push(u);
			}
		}
	}
	
	return d[sink] < INF;
}

int dfs(int v, int flow) {
	if(v == sink || !flow) return flow;
	
	for(; ptr[v] < adj[v].size(); ++ptr[v]) {
		int id = adj[v][ptr[v]];
		if(edges[id].flow && d[edges[id].to] == 1 + d[v]) {
			int pushed = dfs(edges[id].to, min(flow, edges[id].flow));
			if(pushed) {
				edges[id].flow -= pushed;
				edges[id ^ 1].flow += pushed;
				return pushed;
			}
		}
	}
	return 0;
}

int dinic(int source) {
	int flow, pushed;
	
	for(flow = 0; bfs(source); ) {
		memset(ptr, 0, sizeof ptr);
		while(pushed = dfs(source, INF)) flow += pushed;
	}
	
	return flow;
}

int main()
{
	ios_base::sync_with_stdio(false);
	freopen("maxflow.in", "r", stdin);
	freopen("maxflow.out", "w", stdout);
	
	int n, m, a, b, c;
	
	cin >> n >> m;
	for(int i = 1; i <= m; ++i) {
		cin >> a >> b >> c;
		addEdge(a, b, c);
	}
	
	source = 1;
	sink = n;
	
	cout << dinic(source) << '\n';
	
	return 0;
}