Cod sursa(job #750061)

Utilizator SzakatsSzakats Istvan Szakats Data 20 mai 2012 13:09:05
Problema Flux maxim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 4.82 kb
#if 0
#include <stdio.h>
#include <vector>
#include <string>
#include <map>
#include <set>
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <deque>
#include <string.h>

using namespace std;

typedef pair<int, int> PII;

#ifdef _WIN32
#define TYPEOF decltype
#else
#define TYPEOF typeof
#endif

#define FOR(i,s,e) for(int i = s;i < e; i++)
#define TR(i, c) for(TYPEOF(c.begin()) i = c.begin(); i != c.end(); ++i)
#define TRS(i, c, ...) TR(__itr, c) { TYPEOF(*c.begin()) &i = *__itr;  __VA_ARGS__ }
#define TRP(f, s, c, ...) TR(__itr, c) { TYPEOF(c.begin()->first) &f = __itr->first; TYPEOF(c.begin()->second) &s = __itr->second;  __VA_ARGS__ }

#define NMAX 1024

int C[NMAX][NMAX];
int F[NMAX][NMAX];
int P[NMAX];
int Q[NMAX];
int viz[NMAX];

vector<int> G[NMAX];

int N,M;

int bfs() {

	int s = 0, e = 1;
	Q[0] = 1;
	memset(viz, 0, (N+1) * sizeof(int));
	viz[1] = 1;

	while(s < e) {
		int na = Q[s++];
		if(na == N) continue;
		FOR(i,0,G[na].size()) {
			int nb = G[na][i];
			if(viz[nb]) continue;
			int c = C[na][nb], f = F[na][nb];
			if(c > f) viz[nb] = c - f;
			else if(f) viz[nb] = -f;
			else continue;
			P[nb] = na;
			Q[e++] = nb;
		}
	}

	return viz[N];
}

#define INF 0x3f3f3f3f

int main()
{
#if 1
	freopen("critice.in", "r", stdin);
#ifndef MY_STUFF
	freopen("maxflow.out", "w", stdout);
#endif
#endif

	scanf("%d %d", &N, &M);

	FOR(i,0,M) {
		int x,y,c;
		scanf("%d %d %d", &x, &y, &c);
		C[x][y] = c;
		G[x].push_back(y);
		G[y].push_back(x);
	}

	int flow, fmin;

	for(flow = 0; bfs(); )
		FOR(i, 0, G[N].size()) {
			int nod = G[N][i];
			if(!viz[nod] || C[nod][N] == F[nod][N]) continue;
			P[N] = nod;
			fmin = INF;
			for(int nod = N; nod != 1; nod = P[nod])
				fmin = min(fmin, abs(viz[nod]));
			for(int nod = N; nod != 1; nod = P[nod]) {
				int fp = (viz[nod] > 0 ? fmin : -fmin);
				F[ P[nod] ][nod] += fp;
				F[nod][ P[nod] ] -= fp;
			}
			flow += fmin;
		}

	printf("%d\n", flow);

	return 0;
}
#endif

//Code by Patcas Csaba
//Time complexity: O(n*m^2)
//Space complexity: O(m+n)
//Method: Edmonds-Karp dupa capul meu numai pe liste de vecini
//Working time: 30 minutes

#include <stdio.h>
#include <vector>
#include <queue>
#include <string.h>

using namespace std;

#define in_file "maxflow.in"
#define out_file "maxflow.out"

#define VI vector <int>

#define FORN(i,n) for (int i=0;i<n;++i)
#define FOR(i,a,b) for (int i=a;i<=b;++i)
#define ALL(x) x.begin(), x.end()
#define PB push_back
#define S size()

#define inf 111111

#ifndef abs
int abs(int a) {
	return max(a, -a);
}
#endif

struct Tedge
{
	int node,cap,f,inv;
};

int n,m,solution;
vector <vector <Tedge> > g, g2;
VI father, ind;

void bf()
{
	queue <int> l;
	l.push(1);
	father[1]=inf;
	while (!father[n] && !l.empty())
	{
		int node=l.front();
		FORN(i,g[node].S)
		{
			Tedge aux=g[node][i];
			if (!father[aux.node] && aux.cap>aux.f)
			{
				father[aux.node]=node;
				ind[aux.node]=i;
				l.push(aux.node);
			}
		}
		FORN(i,g2[node].S)
		{
			Tedge aux=g2[node][i];
			if (!father[aux.node] && aux.f)
			{
				father[aux.node]=-node;
				ind[aux.node]=i;
				l.push(aux.node);
			}
		}
		l.pop();
	}
}

int IncreaseFlow()
{
	int node=n, flow=inf;
	while (node!=1)
	{
		if (father[node]>0)
		{
			Tedge aux=g[father[node]][ind[node]];
			flow=min(flow,aux.cap-aux.f);
		}
		else 
		{
			Tedge aux=g2[-father[node]][ind[node]];
			flow=min(flow,aux.f);
		}
		if (!flow) return 0;
		node=abs(father[node]);
	}
	node=n;
	while (node!=1)
	{
		if (father[node]>0) 
		{
			g[father[node]][ind[node]].f+=flow;
			g2[node][g[father[node]][ind[node]].inv].f+=flow;
		}
		else 
		{
			g2[-father[node]][ind[node]].f-=flow;
			g[node][g2[-father[node]][ind[node]].inv].f-=flow;
		}
		node=abs(father[node]);
	}
	return flow;
}

void EdmondsKarp()
{
	father.resize(n+1);
	ind.resize(n+1);
	solution=0;
	while (1)
	{
		fill(ALL(father),0);
		bf();
		if (father[n]) 
		{
			FORN(i,g2[n].S)
				if (father[g2[n][i].node] && g2[n][i].cap>g2[n][i].f)	
				{
					father[n]=g2[n][i].node;
					ind[n]=g2[n][i].inv;
					int aux=IncreaseFlow();
					solution+=aux;
				}
		}
		else break;
	}
}

void AddEdge(int node1, int node2, int c)
{
	Tedge aux;
	aux.node=node2;
	aux.cap=c;
	aux.f=0;
	g[node1].PB(aux);

	aux.node=node1;
	aux.cap=c;
	aux.f=0;
	aux.inv=g[node1].S-1;
	g2[node2].PB(aux);
	g[node1][g[node1].S-1].inv=g2[node2].S-1;
}

int main()
{
	FILE* fin=fopen(in_file,"r");
	fscanf(fin,"%d%d",&n,&m);
	g.resize(n+1);
	g2.resize(n+1);
	FORN(q,m)
	{
		int x,y,z;
		fscanf(fin,"%d%d%d",&x,&y,&z);
		AddEdge(x,y,z);
	}
	fclose(fin);

	EdmondsKarp();

	FILE* fout=fopen(out_file,"w");
	fprintf(fout,"%d",solution);
	fclose(fout);

	return 0;
}