Cod sursa(job #581147)

Utilizator niovanIovan Alexandru niovan Data 13 aprilie 2011 20:10:26
Problema Flux maxim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.82 kb
#include <cstdio>
#include <stdlib.h>
#define oo 2000000000
#define NMax 1001
using namespace std;

FILE *fin=fopen("maxflow.in","r"),*fout=fopen("maxflow.out","w");

int t[NMax],cap[NMax][NMax],flux[NMax][NMax],n;

int bfs(int source,int sink)
{
	int Q[NMax],p=0,u=0,i;
	for(i=1;i<=n;++i) t[i]=0;
	Q[0]=source;
	
	while(p<=u)
	{
		int x=Q[p++];
		for(i=source;i<=sink;++i)//pt fiecare nod adiacent
			if(!t[i]&&i!=source)
			if(cap[x][i]-flux[x][i]>0)//mai putem pompa
			{
				Q[++u]=i;//inseram nodul in coada
				t[i]=x;
			}
	}
	if(t[sink])
		return 1;
	return 0;
}

int dinic(int source, int sink)
{
	int flow=0;//fluxul
	int i,min,j;
	while( bfs(source,sink) )//cat timp mai exista un drum de ameliorare
	{
		for(j=source;j<sink;j++)
			if(cap[j][sink]-flux[j][sink]>0)
			{
				min=oo;
				//if(cap[j][sink]-flux[j][sink]<min)
					min=cap[j][sink]-flux[j][sink];
				for(i=j;i!=source;i=t[i])
					if(cap[ t[i] ][i]-flux[ t[i] ][i]<min)
						min=cap[ t[i] ][i]-flux[ t[i] ][i];
					//calculam minimul dintre capacitatile de pe drum
				if(min==oo)
					continue;
				flux[j][sink]+=min;
				flux[sink][j]-=min;
				for(i=j;i!=source;i=t[i])
					flux[ t[i] ][i]+=min,//adaugam minimul la fluxul de pe arcele de pe drum
					flux[i][ t[i] ]-=min;//scadem minimul de pe arcele inverse
				flow+=min;//adaugam fluxul
			}
	}
	return flow;
}

void Citire()
{
	int m,x,y,c;
	fscanf(fin,"%d %d",&n,&m);
	while(m--)
	{
		fscanf(fin,"%d %d %d",&x,&y,&c);
		cap[x][y]=c;
	}
}

void Afisare()
{
	int i,j;
	fprintf(fout,"\nFlux:\n");
	for(i=1;i<=n;i++)
	{
		for(j=1;j<=n;j++)
			if(flux[i][j])
				fprintf(fout,"(%d,%d)=%d\n",i,j,flux[i][j]);
	}
}

int main()
{
	Citire();
	//fprintf(fout,"Flux Maxim = %d\n\n",dinic(1,n));
	fprintf(fout,"%d",dinic(1,n));
	//Afisare();
}