Cod sursa(job #302593)

Utilizator vanila_CPPIonescu Victor Cristian vanila_CPP Data 9 aprilie 2009 02:33:11
Problema Taramul Nicaieri Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.15 kb
//edmonds-karp
#include <iostream>
#include <algorithm>
#define FIN "harta.in"
#define FOUT "harta.out"
#define MAX_N 110
using namespace std;
struct list {int inf; list *urm; } *G[2*MAX_N];
int C[2*MAX_N][2*MAX_N];
int F[2*MAX_N][2*MAX_N];
int SURSA,DEST;
int viz[2*MAX_N];
struct coada {int x,dad;} c[2*MAX_N];
int N;

void build_retea(void){

	freopen(FIN,"rt",stdin);
	freopen(FOUT,"wt",stdout);

	int sumx=0;
	scanf("%d",&N);
	SURSA=2*N+1;
	DEST=SURSA+1;
	list *q;
	
	memset(G,0,sizeof(G));
	int x,y;

	for (int i=1;i<=N;++i){

		scanf("%d%d",&x,&y);
		sumx+=x;

		q=new list;
		q->inf=i+N;
		q->urm=G[DEST];
		G[DEST]=q;
		q=new list;
		q->inf=DEST;
		q->urm=G[i+N];
		G[i+N]=q;
		C[i+N][DEST]=y;

		q=new list;
		q->inf=i;
		q->urm=G[SURSA];
		G[SURSA]=q;
		q=new list;
		q->inf=SURSA;
		q->urm=G[i];
		G[i]=q;
		C[SURSA][i]=x;

		for (int j=1;j<=N;++j){
			if (j!=i){

				q=new list;
				q->inf=j+N;
				q->urm=G[i];
				G[i]=q;
				q=new list;
				q->inf=i;
				q->urm=G[j+N];
				G[j+N]=q;
				C[i][j+N]=1;
			}
		}
	}
	printf("%d\n",sumx);

	fclose(stdin);
}


int minim(int nod){
	int prec=c[nod].dad;
	if (c[prec].x==SURSA) { return C[SURSA][c[nod].x]-F[SURSA][c[nod].x];} else
		return min(minim(prec),C[c[prec].x][c[nod].x]-F[c[prec].x][c[nod].x]);
}

int BF(void){

	int def=0;
	int p=1,u=1;
	memset(viz,0,sizeof(viz));
	viz[SURSA]=1;
	c[p].x=SURSA;
	c[p].dad=0;
	list *q;
	while (p<=u){
		q=G[c[p].x];
		for (;q;q=q->urm){

			if (viz[q->inf]==0 && (C[c[p].x][q->inf]-F[c[p].x][q->inf])>0){
				++u;
				c[u].x=q->inf;
				c[u].dad=p;
				if (q->inf==DEST){
					def=1;
					int mini=minim(u);
					int x=u;
					while (c[x].dad){
						F[c[c[x].dad].x][c[x].x]+=mini;
						F[c[x].x][c[c[x].dad].x]-=mini;
						x=c[x].dad;
					}
					--u;
				} else {viz[q->inf]=1;}
			}
		}
		++p;
	}
	return def;
}


void flux(void){

	int x=1;
	while (x){
		x=BF();
	}

	for (int i=1;i<=N;++i){
		for (int j=1;j<=N;++j){

			if (F[i][j+N]==1){ printf("%d %d\n",i,j);}
		}
	}

	fclose(stdout);
}

int main(void){

	build_retea();
	flux();
	return 0;
}