Cod sursa(job #832014)

Utilizator a_h1926Heidelbacher Andrei a_h1926 Data 9 decembrie 2012 17:12:22
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.82 kb
#include <cstdio>
#include <cstring>
#include <cassert>

#include <algorithm>
#include <vector>
#include <queue>

using namespace std;

const int MaxN = 605;
const int oo = 0x3f3f3f3f;

vector<int> G[MaxN];
int N, M, Edge[MaxN][MaxN], Source, Sink;
int Capacity[MaxN][MaxN], Flow[MaxN][MaxN], MaxFlow, MinCost;
int Cost[MaxN][MaxN], Father[MaxN], Distance[MaxN];
bool InQ[MaxN];
queue<int> Q;

inline void InitBellmanFord(const int &Start) {
    memset(Father, -1, sizeof(Father));
    memset(Distance, oo, sizeof(Distance));
    memset(InQ, 0, sizeof(InQ));
    Distance[Start] = 0;
    Q.push(Start), InQ[Start] = true;
}

bool BellmanFord(const int &Start, const int &End) {
    for (InitBellmanFord(Start); !Q.empty(); Q.pop()) {
        int X = Q.front(); InQ[X] = false;
        for (vector<int>::iterator Y = G[X].begin(); Y != G[X].end(); ++Y) {
            if (Capacity[X][*Y] > Flow[X][*Y] && Distance[X] + Cost[X][*Y] < Distance[*Y]) {
                Distance[*Y] = Distance[X] + Cost[X][*Y], Father[*Y] = X;
                if (!InQ[*Y])
                    Q.push(*Y), InQ[*Y] = true;
            }
        }
    }
    return Father[End] != -1;
}

void MaximumFlow() {
    MaxFlow = MinCost = 0;
    while (BellmanFord(Source, Sink)) {
        int CurrentFlow = N;
        for (int X = Sink; X != Source; X = Father[X])
            CurrentFlow = min(CurrentFlow, Capacity[Father[X]][X] - Flow[Father[X]][X]);
        for (int X = Sink; X != Source; X = Father[X])
            Flow[Father[X]][X] += CurrentFlow, Flow[X][Father[X]] -= CurrentFlow;
        MaxFlow += CurrentFlow, MinCost += CurrentFlow * Distance[Sink];
    }
}

void Read() {
    assert(freopen("cmcm.in", "r", stdin));
    int E; assert(scanf("%d %d %d", &N, &M, &E) == 3);
    for (int i = 1; i <= E; ++i) {
        int X, Y, C; assert(scanf("%d %d %d", &X, &Y, &C) == 3);
        Y += N;
        G[X].push_back(Y), G[Y].push_back(X);
        Edge[X][Y] = i;
        Cost[X][Y] = C, Cost[Y][X] = -C;
        Capacity[X][Y] = 1, Capacity[Y][X] = 0;
    }
    Source = 0, Sink = N + M + 1;
    for (int X = 1; X <= N; ++X) {
        G[Source].push_back(X), G[X].push_back(Source);
        Cost[Source][X] = Cost[X][Source] = 0;
        Capacity[Source][X] = 1;
    }
    for (int X = N + 1; X <= N + M; ++X) {
        G[X].push_back(Sink), G[Sink].push_back(X);
        Cost[X][Sink] = Cost[Sink][X] = 0;
        Capacity[X][Sink] = 1, Capacity[Sink][X] = 0;
    }
}

void Print() {
    assert(freopen("cmcm.out", "w", stdout));
    printf("%d %d\n", MaxFlow, MinCost);
    for (int X = 1; X <= N; ++X)
        for (int Y = N + 1; Y <= N + M; ++Y)
            if (Flow[X][Y] > 0)
                printf("%d ", Edge[X][Y]);
    printf("\n");
}

int main() {
    Read();
    MaximumFlow();
    Print();
    return 0;
}