Cod sursa(job #2470470)

Utilizator PopoviciRobertPopovici Robert PopoviciRobert Data 9 octombrie 2019 11:36:52
Problema Flux maxim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.91 kb
#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define lsb(x) (x & (-x)) 
    
using namespace std;

struct MaxFlow {

	const int INF = 1e9;

	struct Edge {
		int x, y;
		int cap, flx;
		int id;
	};
	
	vector <Edge> edges;
	vector < vector <int> > g;
	vector <int> from, vis;
	int n, now;

	inline void init(int _n) {
		n = _n, now = 0;
		g.resize(n + 1);
		from.resize(n + 1), vis.resize(n + 1);
	}

	inline void addEdge(int x, int y, int z) {
		int id = edges.size();
		g[x].push_back(id);
		edges.push_back({x, y, z, 0, id ^ 1});
		g[y].push_back(id ^ 1);
		edges.push_back({y, x, 0, 0, id});
	}

	inline void clr() {
		for(auto &it : edges) {
			it.flx = 0;
		}
	}

	inline bool bfs(int S, int D) {
		queue <int> Q;
		Q.push(S), vis[S] = ++now;
		while(Q.size()) {
			int nod = Q.front();
			Q.pop();
			for(auto it : g[nod]) {
				int cur = edges[it].y;
				if(edges[it].cap > edges[it].flx && vis[cur] < now) {
					if(cur != D) {
						Q.push(cur);
					}
					vis[cur] = now, from[cur] = it;
				}
			}
		}
		return vis[D] == now;
	}

	inline int solve(int S, int D) {
		int ans = 0;
		while(bfs(S, D)) {
			for(auto it : g[D]) {
				if(vis[edges[it].y] < now || edges[it ^ 1].cap <= edges[it ^ 1].flx) continue;
				from[D] = it ^ 1;
				int mn = INF, nod = D;
				while(nod != S) {
					int id = from[nod];
					mn = min(mn, edges[id].cap - edges[id].flx);
					nod = edges[id].x;
				}
				ans += mn, nod = D;
				while(nod != S) {
					int id = from[nod];
					edges[id].flx += mn, edges[id ^ 1].flx -= mn;
					nod = edges[id].x;
				}
			}
		}
		return ans;
	}
};
   
int main() {
#if 1
    ifstream cin("maxflow.in");
    ofstream cout("maxflow.out");
#endif
    int i, n, m;
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
	
	cin >> n >> m;
	MaxFlow net; net.init(n);
	for(i = 1; i <= m; i++) {
		int x, y, z;
		cin >> x >> y >> z;
		net.addEdge(x, y, z);
	}

	cout << net.solve(1, n);

	return 0;
}