Cod sursa(job #1025182)

Utilizator sziliMandici Szilard szili Data 9 noiembrie 2013 16:21:08
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.71 kb
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <queue>
#include <limits.h>

using namespace std;
int n, m, e;

vector<int> a[602];

int flow[602][602];

//capacity is 1 for [i][j] where there is a connection from i to j
int capacities[602][602];
int costs[602][602];
int mm[602][602];
int prevv[602];

int currentCosts[602];

int bellmanFord(int s){

    for (int i=0; i<=n+m+1; i++){
        currentCosts[i] = INT_MAX;
    }

    currentCosts[0] = 0;

    queue<int> q;
    q.push(s);

    while (!q.empty()){
        int currentNode = q.front();
        q.pop();

        for (int i=0; i<a[currentNode].size(); i++){
            int nextNode = a[currentNode][i];

            if ((capacities[currentNode][nextNode] - flow[currentNode][nextNode]) > 0){

                //relax the edge (currentNode, nextNode)
                if (currentCosts[nextNode] > (currentCosts[currentNode] + costs[currentNode][nextNode])){
                    prevv[nextNode] = currentNode;
                    currentCosts[nextNode] = currentCosts[currentNode] + costs[currentNode][nextNode];
                    q.push(nextNode);
                }
            }
        }
    }

    if (currentCosts[n+m+1] == INT_MAX){
        return 0;
    } else {
        return 1;
    }
}


int main()
{
    freopen("cmcm.in", "r", stdin);
    freopen("cmcm.out", "w", stdout);

    scanf("%d %d %d", &n, &m, &e);

    int from, to, c;
    for (int i=1; i<=e; i++){
        scanf("%d %d %d", &from, &to, &c);
        to += n;
        capacities[from][to] = 1;
        costs[from][to] = c;
        costs[to][from] = -1 * c;
        a[from].push_back(to);
        a[to].push_back(from);
        mm[from][to] = i;
    }

    //add a source
    for (int i=1; i<=n; i++){
        a[0].push_back(i);
        capacities[0][i] = 1;
        costs[0][i] = 0;
    }

    //add a sink
    for (int i=n+1; i<=n+m; i++){
        a[i].push_back(n+m+1);
        capacities[i][n+m+1] = 1;
        costs[i][n+m+1] =0;
    }

    long long totalCost = 0;
    int nr = 0;

    while (bellmanFord(0)){
        nr++;
        int current = n+m+1;

        while (current != 0){
            totalCost += costs[prevv[current]][current];
            flow[prevv[current]][current]++;
            flow[current][prevv[current]]--;
            current = prevv[current];
        }
    }

    printf("%d %lld\n", nr, totalCost);

    for (int i=1; i<=n; i++){
        for (int j=0; j<a[i].size(); j++){
            int nextNode = a[i][j];

            if (flow[i][nextNode] > 0){
                printf("%d ", mm[i][nextNode]);
            }
        }
    }


    return 0;
}