Cod sursa(job #1712235)

Utilizator Mr.RobotElliot Alderson Mr.Robot Data 2 iunie 2016 14:10:05
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.84 kb
#include <iostream>
#include <vector>
#include <queue>
#include <fstream>

using namespace std;

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

#define N 603
#define mult 2000000000
int n, m, e, x, y, z, cost[N][N], cap[N][N], flow[N][N], tata[N], dist[N], inq[N], muchie[N][N];
vector < int > l[N];

int BELLMAN()
{
    queue < int > q;

    for( int i = 1; i <= n + m + 2; ++ i )
    {
        dist[i] = mult;
        inq[i] = 0;
    }

    dist[1] = 0;
    inq[1] = 1;
    q.push( 1 );

    while( !q.empty() )
    {
        int nod = q.front();
        q.pop();
        inq[nod] = 0;

        for( vector < int > :: iterator it = l[nod].begin(); it != l[nod].end(); ++ it )
        {
            if( cap[nod][*it] > flow[nod][*it] && dist[nod] + cost[nod][*it] < dist[*it] )
            {
                dist[*it] = dist[nod] + cost[nod][*it];
                tata[*it] = nod;

                if( inq[*it] == 0 )
                {
                    inq[*it] = 1;
                    q.push(*it);
                }
            }
        }
    }
    if( dist[n+m+2] == mult )
        return 0;
    return 1;
}

int main()
{
    in >> n >> m >> e;
    int sol = 0;
    for( int i = 1; i <= e; ++ i )
    {
        in >> x >> y >> z;
        ++ x;
        y += n + 1;

        l[x].push_back( y );
        l[y].push_back( x );

        cost[x][y] = z;
        cost[y][x] = -z;
        cap[x][y] = 1;
        cap[y][x] = 0;

        muchie[x][y] = i;
    }

    for( int i = 2; i <= n + 1; ++ i )
    {
        cost[1][i] = 0;
        cost[i][1] = 0;
        cap[1][i] = 1;
        cap[i][1] = 0;
        l[1].push_back(i);
    }

    for( int i = n + 2; i <= n + m + 1; ++ i )
    {
        cost[i][n+m+2] = 0;
        cost[n+m+2][i] = 0;
        cap[i][n+m+2] = 1;
        cap[n+m+2][i] = 0;
        l[i].push_back(n+m+2);
    }

    while( BELLMAN() )
    {
        int fmin = mult;
        for( int aux = n + m + 2; tata[aux]; aux = tata[aux] )
            if( cap[tata[aux]][aux] - flow[tata[aux]][aux] < fmin )
                fmin = cap[tata[aux]][aux] - flow[tata[aux]][aux];

        for( int aux = n + m + 2; tata[aux]; aux = tata[aux] )
        {
            flow[tata[aux]][aux] += fmin;
            flow[aux][tata[aux]] -= fmin;
        }

        sol += fmin * dist[n+m+2];
    }
    int nr = 0;
    for( int i = 2; i <= n + 1; ++ i )
        for( int j = n + 2; j <= n + m + 1; ++ j )
            if( flow[i][j] && cap[i][j] )
            {
                ++ nr;
                break;
            }

    out << nr << " " << sol << '\n';
    for( int i = 2; i <= n + 1; ++ i )
        for( int j = n + 2; j <= n + m + 1; ++ j )
            if( flow[i][j] && cap[i][j] )
            {
                out << muchie[i][j] << " ";
            }

    return 0;
}