Cod sursa(job #922555)

Utilizator paul_gabryelPaul Buda paul_gabryel Data 22 martie 2013 14:20:47
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.3 kb

#include <fstream>
#include <vector>
#include <cstring>
#include <queue>

using namespace std;

ifstream in ("cmcm.in");
ofstream out ("cmcm.out");

#define oo 0x3f3f3f3f

const int N = 654;

vector<pair<int,int> > G[N];
int n,m,EDGE[N][N],C[N][N],DIST[N],start,stop,T[N],ed,SOL,CUPLAJ;
bool inQ[N];


void READ ()
{

    in>>n>>m>>ed;

    for( int x,y,c,i=1 ; i <= ed ; ++i )
    {

        in>>x>>y>>c;

        G[x].push_back(make_pair(n+y,c));
        G[n+y].push_back(make_pair(x,-c));

        C[x][n+y]=1;

        EDGE[x][y+n]=i;

    }

}

bool BFS ()
{

    queue<int> Q;

    memset(DIST,oo,sizeof(DIST));

    DIST[start]=0;
    inQ[start]=1;

    for( Q.push(start) ; Q.size() ; Q.pop() )
    {

        int nod=Q.front();
        inQ[nod]=0;
        for(vector<pair<int,int> >::iterator it=G[nod].begin() ; it < G[nod].end() ; ++it )
            if( DIST[it->first] > DIST[nod]+it->second && C[nod][it->first] )
            {

                DIST[it->first]=DIST[nod]+it->second;
                T[it->first]=nod;

                if( !inQ[it->first] )
                {
                    inQ[it->first]=1;
                    Q.push(it->first);
                }
            }
    }

    return DIST[stop]!=oo;

}

void SOLVE ()
{

    start=0;
    stop=n+m+1;

    for( int i=1 ; i <= n ; ++i )
    {

        G[start].push_back(make_pair(i,0));
        G[i].push_back(make_pair(start,0));

        C[start][i]=1;

    }

    for( int i=1 ; i <= m ; ++i )
    {

        G[stop].push_back(make_pair(n+i,0));
        G[n+i].push_back(make_pair(stop,0));

        C[n+i][stop]=1;

    }

    for( ; BFS() ; SOL+=DIST[stop] )
        for( int nod=stop ; nod != start ; nod=T[nod] )
        {
            --C[T[nod]][nod];
            ++C[nod][T[nod]];
        }

    for( int i=1 ; i <= n ; ++i )
        for( int j=1 ; j <= m ; ++j )
            if( EDGE[i][n+j] && !C[i][n+j] )
                ++CUPLAJ;

}

void PRINT ()
{

    out<<CUPLAJ<<' '<<SOL<<'\n';

    for( int i=1 ; i <= n ; ++i )
        for( int j=1 ; j <= m ; ++j )
            if( EDGE[i][n+j] && !C[i][n+j] )
                out<<EDGE[i][n+j]<<' ';

}

int main ()
{

    READ ();
    SOLVE ();
    PRINT ();

    return 0;

}