Cod sursa(job #1825692)

Utilizator andreicoman299Coman Andrei andreicoman299 Data 9 decembrie 2016 16:05:52
Problema Cuplaj maxim in graf bipartit Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.72 kb
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <cctype>
#include <string.h>

#define BUF_SIZE 1<<17
char buffer[BUF_SIZE];
int pbuf = BUF_SIZE;
FILE *fi, *fo;
inline char nextch(){
    if(pbuf == BUF_SIZE){
        fread(buffer, BUF_SIZE, 1, fi);
        pbuf=0;
    }
    return buffer[pbuf++];
}
inline int nextnum(){
    int a = 0;
    char c = nextch();
    while(!isdigit(c))
        c = nextch();
    while(isdigit(c)){
        a = a*10+c-'0';
        c = nextch();
    }
    return a;
}

#define MAXN 10000

std::vector < int > G[1 + MAXN];
bool viz[1 + MAXN];
int left[1 + MAXN], right[1 + MAXN];

int src(int node){
    if(viz[node]) return 0;
    viz[node] = 1;

    for(auto y: G[node])
        if(!right[y]){
            left[node] = y;
            right[y] = node;
            return 1;
        }
    for(auto y: G[node])
        if(src(right[y])){
            left[node] = y;
            right[y] = node;
            return 1;
        }
    return 0;
}

int main(){
    fi = fopen("cuplaj.in","r");
    fo = fopen("cuplaj.out","w");

    int n = nextnum(), m = nextnum(), edges = nextnum();
    for(int i = 0; i < edges; i++){
        int x = nextnum(), y = nextnum();
        G[x].push_back(y);
    }

    int flag = 1;
    while(flag){
        flag = 0;
        memset(viz, 0, sizeof(viz));
        for(int i = 1; i <= n; i++)
            if(!left[i])
                flag = flag | src(i);
    }

    int cuplaj = 0;
    for(int i = 1; i <= n; i++)
        if(left[i]) cuplaj++;

    fprintf(fo,"%d\n", cuplaj);
    for(int i = 1; i <= n; i++)
        if(left[i]) fprintf(fo,"%d %d\n", i, left[i]);
    fclose(fi);
    fclose(fo);
    return 0;
}