Cod sursa(job #2533758)

Utilizator mlupseLupse-Turpan Mircea mlupse Data 29 ianuarie 2020 17:49:01
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.1 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;
	
}