Cod sursa(job #962947)

Utilizator alexeiIacob Radu alexei Data 16 iunie 2013 01:36:37
Problema Flux maxim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.57 kb
/* maxflow.cpp
 *
 *  Created on: Jun 16, 2013
 *      Author: alexei
 */

#include <cstdio>
#include <cstring>
#include <cstdlib>

#include <deque>
#include <queue>
#include <vector>
#include <bitset>
#include <string>
#include <algorithm>

#include <iostream>

typedef unsigned int uint;
typedef long long    ll;

#define INF 0x3f3f3f3f


template< class D, int N >
class Graph_Flow{

public:

	int source, sink;
	std::vector< int > G[N];

	int T[N];
	D Cap[N][N];

	bool viz[N];

	Graph_Flow( int source, int sink ) : source(source), sink(sink)
	{

	}

	Graph_Flow(){
		source = sink = 0;
	}

	/*
	 * Custom
	 */

	void build_graph( int _source, int _sink, int Edges )
	{
		source = _source;
		sink   = _sink;

		for( int i = 0, a1, a2, cap; i < Edges; ++i )
		{
			std::cin >> a1 >> a2 >> cap;
			add_link( a1, a2, cap );
		}
	}

	void add_link( int node1 , int node2, int cap )
	{
		G[node1].push_back(node2);
		G[node2].push_back(node1);

		Cap[node1][node2] = cap;
	}

	void link_to_source( int node, D cap )
	{
		G[source].push_back(node);
		Cap[source][node] = cap;
	}

	void link_to_sink( int node, D cap )
	{
		G[sink].push_back(node);
		Cap[node][sink] = cap;
	}

	bool BF()
	{
		memset( viz, 0, sizeof(viz) );

		std::queue< int > Q;

		Q.push( source );
		viz[source] = true;

		while( !Q.empty() )
		{
			int node = Q.front();
			Q.pop();

			if( node == sink )
				continue;

			for( uint i = 0, sz = G[node].size(); i < sz; ++i )
			{
				int v = G[node][i];

				if( viz[v] || !Cap[node][v] )
					continue;

				Q.push(v);
				viz[v] = true;
				T[v] = node;
			}
		}

		return viz[sink];
	}

	/*
	 * Dinic O( V^2 * E )
 	 */

	D max_flow()
	{
		D flow = 0, fmin;
		int node;

		while( BF() )
		{
			for( uint i = 0, sz = G[sink].size(); i < sz; ++i )
			{
				node = G[ sink ][ i ];

				if( !viz[node] || !Cap[node][sink] )
					continue;

				T[sink] = node;

				fmin = INF;

				for( node = sink; node != source; node = T[node] )
					fmin = std::min( fmin, Cap[ T[node] ][ node ] );

				for( node = sink; node != source; node = T[node] )
				{
					Cap[ T[node] ][ node ] -= fmin;
					Cap[ node ][ T[node] ] += fmin;
				}

				flow += fmin;
			}
		}

		return flow;
	}

	void reset()
	{
		memset( Cap, 0, sizeof(Cap) );

		for( int i = 0; i < N; ++i ){
			G[i].clear();
		}
	}

};

int main()
{
#ifndef ONLINE_JUDGE

	std::string TASK_ID("maxflow");
	freopen( (TASK_ID + ".in").c_str(), "r", stdin );
	freopen( (TASK_ID + ".out").c_str(), "w", stdout );

#endif

	int N, M;
	std::cin >> N >> M;

	Graph_Flow<int,1024> G;

	G.build_graph( 1, N, M );
	std::cout << G.max_flow() << "\n";

	return 0;
}