Cod sursa(job #791116)

Utilizator visanrVisan Radu visanr Data 22 septembrie 2012 23:18:31
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.58 kb
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;

#define nmax 610
#define oo 0x3f3f3f3f
#define pb push_back

int Capacity[nmax][nmax], CurrentFlow[nmax][nmax], Cost[nmax][nmax], Dist[nmax], Father[nmax], ind[nmax][nmax];
int N, M, E, X, Y, C, S, D;
vector<int> G[nmax];
bool InQueue[nmax];

int BF()
{
    memset(Dist, oo, sizeof(Dist));
    Dist[S] = 0;
    queue<int> Q; Q.push(S);
    InQueue[S] = 1;
    while(!Q.empty())
    {
        int node = Q.front(); Q.pop(); InQueue[node] = 0;
        for(vector<int> :: iterator it = G[node].begin(); it != G[node].end(); ++it)
            if(Capacity[node][*it] > CurrentFlow[node][*it] && Dist[*it] > Dist[node] + Cost[node][*it])
            {
                Dist[*it] = Dist[node] + Cost[node][*it];
                Father[*it] = node;
                if(!InQueue[*it])
                {
                    InQueue[*it] = 1;
                    Q.push(*it);
                }
            }
    }
    return (Dist[D] != oo);
}

void Flow()
{
    int now = 0, maxFlow = 0, minFlow, i, j;
    while(BF())
    {
        minFlow = oo;
        for(int node = D; node != S; node = Father[node])
            minFlow = min(minFlow, Capacity[Father[node]][node] - CurrentFlow[Father[node]][node]);
        if(minFlow)
        {
            for(int node = D; node != S; node = Father[node])
            {
                CurrentFlow[Father[node]][node] += minFlow;
                CurrentFlow[node][Father[node]] -= minFlow;
                maxFlow += minFlow * Cost[Father[node]][node];
            }
        }
    }
    for(i = 1; i <= D; i++)
        for(j = 1; j <= D; j++)
            if(CurrentFlow[i][j] == 1)
                now ++;
    printf("%i %i\n", now / 3, maxFlow);
    for(i = 1; i <= D; i++)
        for(j = 1; j <= D; j++)
            if(CurrentFlow[i][j] == 1 && i != S && j != D)
                printf("%i ", ind[i][j]);
}

int main()
{
    freopen("cmcm.in", "r", stdin);
    freopen("cmcm.out", "w", stdout);
    int i;
    scanf("%i %i %i", &N, &M, &E);
    S = 1; D = N + M + 2;
    for(i = 1; i <= E; i++)
    {
        scanf("%i %i %i", &X, &Y, &C);
        X ++, Y += N + 1;
        G[X].pb(Y); G[Y].pb(X);
        Capacity[X][Y] = 1;
        Cost[X][Y] = C; Cost[Y][X] = -C;
        ind[X][Y] = i;
        if(Capacity[S][X] == 0) G[S].pb(X), G[X].pb(S);
        if(Capacity[Y][D] == 0) G[Y].pb(D), G[D].pb(Y);
        Capacity[S][X] = Capacity[Y][D] = 1;
    }
    Flow();
    return 0;
}