Cod sursa(job #2959568)

Utilizator andrei_marciucMarciuc Andrei andrei_marciuc Data 1 ianuarie 2023 17:05:26
Problema Flux maxim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.78 kb
#include <algorithm>
#include <fstream>
#include <vector>
using namespace std;

ifstream cin( "maxflow.in" );
ofstream cout( "maxflow.out" );

struct Dinic {
	struct Edge {
		int to, flow, init, next;
	};

	int N, S, D;
	
	vector<Edge> G;
	vector<int> head, at, h;


	Dinic( int N, int S, int D ) : N( N ), S( S ), D( D ), head( N, -1 ), h( N, -1 ) { }

	void AddEdge( int from, int to, int capacity ) {
		G.push_back( { to, capacity, capacity, (int)G.size() } );
		swap( head[ from ], G.back().next );
		G.push_back( { from, 0, 0, (int)G.size() } );
		swap( head[ to ], G.back().next );
	} 

	bool Bfs() {
		fill( h.begin(), h.end(), -1 );
		h[ S ] = 0;
		vector<int> q = { S };
		for( int it = 0; it < (int)q.size(); it++ ) {
			int nod = q[ it ];
			for( int i = head[ nod ]; i != -1; i = G[ i ].next ) {
				if( G[ i ].flow && h[ G[i].to ] == -1 ) {
					h[ G[ i ].to ] = 1 + h[ nod ], q.push_back( G[ i ].to );
					if( G[ i ].to == D )
						return true;
				}
			}
		}
		return false;
	}

	int Dfs( int nod, int flow_max ) {
		if( nod == D || flow_max == 0 )
			return flow_max;
		
		while( at[ nod ] != -1 ) {
			Edge& e = G[ at[ nod ] ];
			if( h[ e.to ] == 1 + h[ nod ] && e.flow ) {
				int added = Dfs( e.to, min( flow_max, e.flow ) );
				if( added ) {
					e.flow -= added;
					G[ at[ nod ] ^ 1 ].flow += added;
					return added;
				} else at[ nod ] = G[ at[ nod ] ].next;
			} else at[ nod ] = G[ at[ nod ] ].next;
		}
		return 0;
	}


	int ComputeFlow() {
		int rez = 0;
		while( Bfs() ) {
			at = head;
			int x;
			while( ( x = Dfs( S, 1e9 ) ) )
				rez += x;
		}
		return rez;
	}
};


int n, m;

int main()
{
	cin >> n >> m;

	Dinic flux( n + 1, 1, n );

	int from, to, cap;
	while( m-- ) {
		cin >> from >> to >> cap;
		flux.AddEdge( from, to, cap );
	}

	cout << flux.ComputeFlow() << '\n';
	return 0;
}