Cod sursa(job #1411986)

Utilizator toranagahVlad Badelita toranagah Data 1 aprilie 2015 02:06:42
Problema Cuplaj maxim de cost minim Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 2.59 kb
//Problem cmcm
#include <algorithm>
#include <fstream>
#include <iostream>
#include <queue>
#include <vector>
using namespace std;

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

const int MAX_N = 605;
const int INF = 1e9;

int N, M, E;
vector<int> graph[MAX_N];
int cost[MAX_N][MAX_N];
int cap[MAX_N][MAX_N];
int flow[MAX_N][MAX_N];
int eInd[MAX_N][MAX_N];
int father[MAX_N];
int dist[MAX_N];
bool inQ[MAX_N];
int source, sink;
int numCuplaj, costCuplaj;

void readin() {
    fin >> N >> M >> E;
    for (int i = 1, a, b, c; i <= E; i += 1) {
        fin >> a >> b >> c;
        eInd[a][b] = i;
        b = N + b;
        graph[a].push_back(b);
        graph[b].push_back(a);
        cap[a][b] = 1;
        cost[a][b] = c;
        cost[b][a] = -c;
    }

    source = N + M + 2;
    sink = N + M + 3;
    for (int i = 1; i <= N; i += 1) {
        graph[source].push_back(i);
        graph[i].push_back(source);
        cap[source][i] = 1;
    }

    for (int i = N + 1; i <= N + M; i += 1) {
        graph[sink].push_back(i);
        graph[i].push_back(sink);
        cap[i][sink] = 1;
    }
}

inline int cp(int a, int b) {
    return cap[a][b] - flow[a][b];
}

bool findAugPath() {
    fill(father, father + MAX_N, 0);
    fill(inQ, inQ + MAX_N, 0);
    fill(dist, dist + MAX_N, INF);

    queue<int> q;
    q.push(source);
    dist[source] = 0;

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

        if (node == sink) return true;

        for (auto v: graph[node]) {
                if (cp(node, v) > 0 && dist[node] + cost[node][v] < dist[v]) {
                dist[v] = dist[node] + cost[node][v];
                father[v] = node;
                if (!inQ[v]) {
                    q.push(v);
                    inQ[v] = 1;
                }
            }
        }
    }
    return false;
}

void maxflow() {
    while (findAugPath()) {
        int newFlow = INF;
        for (int v = sink; v != source; v = father[v]) {
            newFlow = min(newFlow, cp(father[v], v));
        }
        numCuplaj += newFlow;
        for (int v = sink; v != source; v = father[v]) {
            costCuplaj += newFlow * cost[father[v]][v];
            flow[father[v]][v] += newFlow;
            flow[v][father[v]] -= newFlow;
        }
    }
}

void printout() {
    fout << numCuplaj << ' ' << costCuplaj << endl;
    for (int i = 1; i <= N; i += 1) {
        for (int j = 1; j <= M; j += 1) {
            if (flow[i][j + N] == 1) {
                fout << eInd[i][j] << ' ';
            }
        }
    }
}


int main() {
    readin();
    maxflow();
    printout();
    return 0;
}