Cod sursa(job #486299)

Utilizator MarioYCMario Ynocente Castro MarioYC Data 21 septembrie 2010 01:09:17
Problema Cuplaj maxim in graf bipartit Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.45 kb
#include <cstdio>
#include <vector>
#include <cstring>

using namespace std;

#define MAX_V1 10000
#define MAX_V2 10000
#define MAX_E 100000

int V1,V2,l[MAX_V1],r[MAX_V2];
int E,to[MAX_E],next[MAX_E],last[MAX_V1];
bool visited[MAX_V1];

void init(){
	memset(last,-1,sizeof(int)*V1);
	E = 0;
}
 
void add_edge(int u, int v){
	to[E] = v, next[E] = last[u]; last[u] = E; ++E;
}

bool pairup(int u){
    if (visited[u])  return false;
    visited[u] = true;
    
    for(int e = last[u];e!=-1;e = next[e]){
        int v = to[e];
        
        if(r[v]==-1 || pairup(r[v])){
            l[u] = v;
            r[v] = u;
            return true;
        }
    }
    
    return false;
}

int hopcroft_karp(){
    bool change = true;
    memset(l,-1,sizeof(int)*V1);
    memset(r,-1,sizeof(int)*V2);
    
    while(change){
        change = false;
        memset(visited,false,sizeof(bool)*V1);
        
        for(int i = 0;i<V1;++i)
            if(l[i]==-1) change |= pairup(i);
    }
    
    int ret = 0;
    
    for(int i = 0;i<V1;++i)
        if(l[i]!=-1) ++ret;
    
    return ret;
}

int main(){
    freopen("cuplaj.in","r",stdin);
    freopen("cuplaj.out","w",stdout);    
    
    int e,u,v;
    scanf("%d %d %d",&V1,&V2,&e);
	
	init();
	
    while(e--){
        scanf("%d %d",&u,&v);
        --u; --v;
        add_edge(u,v);
    }
    
    printf("%d\n",hopcroft_karp());
    
    for(int i = 0;i<V1;++i)
        if(l[i]!=-1) printf("%d %d\n",1+i,1+l[i]);
    
    return 0;
}