Cod sursa(job #1469685)

Utilizator adina0822Ciubotaru Adina-Maria adina0822 Data 9 august 2015 11:03:07
Problema Cuplaj maxim in graf bipartit Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 2.15 kb
using namespace std;
#include <fstream>
#define MAXN 20010


FILE *f=fopen ("cuplaj.in", "r");
FILE *g=fopen ("cuplaj.out", "w");

struct list
{
    int node,cap,flow;
    list *nxt, *dup;
};

typedef list* plist;
plist edge[MAXN],adj[MAXN];

int n,m,q[MAXN],sel[MAXN],src,sink;


void read();
void alloc_edge(plist &nou,plist &dup,int i,int j)
{
    nou=new list;
    dup=new list;
    nou->node=j;
    dup->node=i;
    nou->dup=dup;
    dup->dup=nou;
    nou->nxt=adj[i];
    dup->nxt=adj[j];
    adj[i]=nou;
    adj[j]=dup;

}

int BFS(int,int);



int main ()
{
   read();
   int cuplaj=0;
   while(BFS(src,sink)) cuplaj++;
   fprintf(g,"%d\n",cuplaj);
   for(int i=1;i<=n; i++)
    {
        for (plist it = adj[i]; it; it = it->nxt)
            if (it->flow == 1)
                fprintf(g, "%d %d\n", i, it->node - n);
    }



  return 0;
}

void read()
{
    int cnt_edges,x,y;
    plist nou,dup;
    fscanf(f,"%d%d%d",&n,&m,&cnt_edges);
    while(cnt_edges--)
    {
        fscanf(f,"%d%d",&x,&y);
        alloc_edge(nou,dup,x,y+n);
        nou->cap=1;
        nou->flow=dup->cap=dup->flow=0;
    }

    src=0;

    for(int i=1; i<=n; i++)
    {
        alloc_edge(nou,dup,src,i);
        nou->cap=1;
        nou->flow=dup->cap=dup->flow=0;
    }
    sink=n+m+1;
    for(int i=n+1; i<=n+m+1; i++)
    {
        alloc_edge(nou,dup,i,sink);
        nou->cap=1;
        nou->flow=dup->cap=dup->flow=0;
    }

}


int BFS(int src, int sink)
{
    int h,t;
    plist it;
    for(int i=0; i<=n+m+1; i++) sel[i]=0;
    edge[src]=0;
    h=t=0;
    q[0]=src;
    sel[src]=1;
    for(;h<=t;h++)
    {
        for (it = adj[q[h]]; it; it = it->nxt)
            if ((it->cap - it->flow) > 0 && !sel[it->node])
            {
                sel[q[++ t] = it->node] = 1;
                edge[it->node] = it;
                if (it->node == sink)
                {
                    for (it = edge[sink]; it; it = edge[it->dup->node])
                        it->flow ++, it->dup->flow --;
                    return 1;
                }
            }
    }

    return 0;
}