Cod sursa(job #373291)

Utilizator titusuTitus C titusu Data 13 decembrie 2009 12:38:25
Problema Cuplaj maxim in graf bipartit Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 2.12 kb
using namespace std;
#include <cstdio>
#include <cassert>
#define MAX 100010

struct muchie{
	int unu,doi, capflux;
	muchie * next;
};

int n, //noduri in stanga
	m, //noduri in dreapta
	tata[2*MAX], // vector de tati la bfs
	cuplaj, // nr de muchii din cuplaj
	nrBFS,
	xxx;
muchie * G[MAX*2], * tataM[2*MAX];


void addMuchie(int i,int j, int cf){
	muchie *p=new muchie;
	p->unu=i;
	p->doi=j;
	p->capflux = cf;
	p->next=G[i];
	G[i]=p;
}

void read(){
	int nrM,i,j;
	scanf("%d%d%d",&n,&m,&nrM);
	for(i=0;i<=n+m+1;++i)
		G[i]=NULL;
	for( ; nrM ;nrM--){
		scanf("%d%d",&i,&j);
		addMuchie(i,j+n,1);
		addMuchie(j+n,i,0);
	}
	for(i=1; i<=n;i++){
		addMuchie(0,i,1);
		addMuchie(i,0,0);
	}
	for(i=n+1; i<=n+m;i++){
		addMuchie(i,n+m+1,1);
		addMuchie(n+m+1,i,0);
	}
}

int bfs(int s,int d){
	nrBFS++;
	int coada[2*MAX],st=1,dr=1,k,i;
	for(i=0;i<=n+m+1;++i)
		tata[i]=-2;
	coada[1]=s,tata[s]=-1;
	while(st<=dr){
		k=coada[st++];
		for(muchie *p = G[k] ; p; p = p->next){
			i=p->doi;
			if(tata[i]==-2 && p->capflux){
				coada[++dr] = i;
				tata[i]=k;
				
			}
		}
		if(k==d)
			return 1;
	}
	return 0;
}

muchie * getMuchieAddr(int i,int j){
	for(muchie * p = G[i]; p ; p=p->next)
		if(p->doi == j)
			return p;
	return NULL;
}

void e_k(){
	int k,i,dcur;
	muchie *p;
	while(bfs(0,n+m+1)){
		k = n+m+1;
		dcur=5;
		k=n+m+1;
		while( (i=tata[k])!=-1 ){
			p=getMuchieAddr(i,k);
			assert(p!=NULL);
			if(p->capflux<dcur)
				dcur=p->capflux;
			k=i;
		}
		cuplaj+=dcur;
		k=n+m+1;
		while( (i=tata[k])!=-1 ){
			p=getMuchieAddr(i,k);
			assert(p!=NULL);
			p->capflux -= dcur;
			p=getMuchieAddr(k,i);
			assert(p!=NULL);
			p->capflux += dcur;
			k=i;
		}
	}
}

void write(){
	freopen("cuplaj.out","w",stdout);
	printf("%d\n",cuplaj);
	int gasit;muchie *p;
	for(int i=1;i<=n;i++)
		for(p=G[i],gasit=0; p && !gasit; p=p->next)
			if(p->doi>n && p->capflux==0)
				printf("%d %d \n",i,p->doi-n),gasit=1;
}

void afisGraf(){
	for(int i=0;i<=n+m+1;i++){
		for(muchie * p=G[i]; p ; p = p->next)
			printf("(%d,%d,%d)", p->unu, p->doi, p->capflux);
		printf("\n");
	}
}

int main(){
	freopen("cuplaj.in", "r" , stdin);
	read();
//	afisGraf();
	e_k();
	write();
	return 0;
}