Cod sursa(job #1163519)

Utilizator dumytruKana Banana dumytru Data 1 aprilie 2014 13:59:15
Problema Cuplaj maxim in graf bipartit Scor 26
Compilator cpp Status done
Runda Arhiva educationala Marime 2.11 kb
#include <fstream>
#include <iostream>
#include <vector>
#include <queue>
#include <string.h>
#define nmax 10001

using namespace std;

vector<vector<int> > graf;
vector<pair<int,int> > sol;
queue<int>q;
int l,r,n,m,source,sink,oo=110000,from[nmax],isVisited[nmax],cap[nmax][nmax],flux[nmax][nmax];
int minim(int a, int b)
{
    if(a>b)return b;
    return a;
}

int findpath()
{
    int CN,i,ln,minCap=oo;
    bool isPath;
    q.push(source);
    isPath=false;

    memset(isVisited, 0, sizeof(isVisited));
    isVisited[source]=1;

    while(!q.empty() && !isPath)
    {
        CN=q.front();q.pop();
        ln=graf[CN].size();
        for(i=0;i<ln;i++)
        {
            if( cap[CN][ graf[CN][i] ] - flux[CN][ graf[CN][i] ] > 0 && !isVisited[graf[CN][i]])
            {
                from[graf[CN][i]] = CN;
                if(graf[CN][i]==sink){isPath=true;break;}
                q.push(graf[CN][i]);
                isVisited[graf[CN][i]]=1;
            }
        }
    }
    while(!q.empty()) q.pop();
    if(!isPath)return 0;
    CN=sink;int x,y;
    while(CN!=source)
    {
        y=x;
        minCap=minim(minCap,cap[from[CN]][CN]-flux[from[CN]][CN]);
        x=CN;
        CN=from[CN];
    }
    sol.push_back(make_pair(x,y));
    CN=sink;
    while(CN!=source)
    {
        flux[from[CN]][CN]+=minCap;
        flux[CN][from[CN]]-=minCap;
        CN=from[CN];
    }
    return minCap;
}

int maxflow()
{
    int r=0,res=0;
    do
    {
        res=findpath();
        r+=res;
    }while(res);
    return r;
}

int main()
{
    ifstream f("cuplaj.in");
    ofstream g("cuplaj.out");
    int i,u,v;
    f>>l>>r>>m;
    n=l+r+1;
    graf.resize(n+1);
    for(i=1;i<=m;i++)
    {
        f>>u>>v;
        v+=l;
        graf[u].push_back(v);
        graf[v].push_back(u);
        graf[0].push_back(u);
        graf[v].push_back(n);
        cap[u][v]+=1;
        cap[0][u]=1;
        cap[v][n]=1;
    }
    source=0;sink=n;
    g<<maxflow()<<'\n';
    for(i=0;i<sol.size();i++)
        g<<sol[i].first<<' '<<sol[i].second-l<<'\n';
    return 0;
}