Cod sursa(job #796415)

Utilizator mihaiSimuSimu Mihai mihaiSimu Data 11 octombrie 2012 13:55:05
Problema Cuplaj maxim in graf bipartit Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 1.89 kb
#include <stdio.h>
#include <string.h>
#include <vector>
#include <queue>
using namespace std;
const int INF=1000000;
int n,m,s,t;
int a[20005][20005];
int parent[20005];
vector< int > G[20005];
int aa(int i){return i;}
int bb(int i){return i+n;}
bool viz[20005];

int f;

int min(int a,int b){return a<b?a:b;}

void augPath(int nod,int minFlow){
	if(nod==s) {f=minFlow;}
	else{
		augPath(parent[nod],min(minFlow,a[parent[nod]][nod]));
		a[parent[nod]][nod]-=f;
		a[nod][parent[nod]]+=f;
	}
}

void maxFlow(){
	int u,v,maxFlow=0;;
	while(true){
		queue<int> q;
		memset(viz,0,sizeof(viz));
		viz[s]=1;q.push(s);
		while(!q.empty()){
			u=q.front();q.pop();
			if(u==t) break;
			for(int i=0;i<G[u].size();i++){
				if(!viz[G[u][i]] && a[u][G[u][i]]>0){
					v=G[u][i];viz[v]=1;q.push(v);		
					parent[v]=u;
				}
			}
		}
		if(!viz[t]) break;
			augPath(t,INF);
			maxFlow+=f;
	}
	printf("%d\n",maxFlow);
	
	memset(viz,0,sizeof(viz));
	queue<int> q; q.push(s);viz[s]=1;
	while(!q.empty()){
		u=q.front();q.pop();
		if(u==t) break;
		for(int i=0;i<G[u].size();i++){
			if(!viz[G[u][i]] && a[u][G[u][i]]>0){
				v=G[u][i];viz[v]=1;q.push(v);		
				parent[v]=u;
			}
		}
	}

	for(int i=0;i<=n;i++){
		//if(viz[i]){
			for(int j=0;j<G[i].size();j++){
				if(G[i][j]>n)
				if(a[G[i][j]][i]>0 )
					printf("%d %d\n",i,(G[i][j]-n));
			
			}
		//}
	}

}


int main(){
	int e,x,y;
	freopen("cuplaj.in","r",stdin);
	freopen("cuplaj.out","w",stdout);

	scanf("%d %d %d",&n,&m,&e);s=0;t=n+m+1;
	for(int i=0;i<e;i++){
		scanf("%d %d",&x,&y);
		G[aa(x)].push_back(bb(y));
		G[bb(y)].push_back(aa(x));
		a[aa(x)][bb(y)]=1;
	}

	for(int i=1;i<=n;i++){
		G[s].push_back(aa(i));
		G[aa(i)].push_back(s);
		a[s][aa(i)]=1;
	}

	for(int i=1;i<=m;i++){
		G[bb(i)].push_back(t);
		G[t].push_back(bb(i));
		a[bb(i)][t]=1;
	}

	maxFlow();

	return 0;
}