Cod sursa(job #1251441)

Utilizator okros_alexandruOkros Alexandru okros_alexandru Data 29 octombrie 2014 14:50:30
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.75 kb
#include <fstream>
#include <vector>
#include <queue>

#define Nmax 610
#define oo (1 << 30)
#define Neighbour Graph[Node][i]
#define pb push_back

using namespace std;

vector <int> Graph[Nmax], Solution;
queue <int> Queue;
int N, M, minCost, Source, Destination, Father[Nmax], Distance[Nmax];
int Cost[Nmax][Nmax], Edge[Nmax][Nmax];
bool Capacity[Nmax][Nmax], inQueue[Nmax];

bool bellmanFord() {

    int i, Node;

    for(i = Source; i <= Destination; i++)
        Distance[i] = oo;

    Queue.push(Source);
    Distance[Source] = 0;

    while(!Queue.empty()) {

        Node = Queue.front();
        Queue.pop();
        inQueue[Node] = false;

        for(i = 0; i < Graph[Node].size(); i++)
            if(Capacity[Node][Neighbour] && Distance[Neighbour] > Distance[Node] + Cost[Node][Neighbour]) {

                Distance[Neighbour] = Distance[Node] + Cost[Node][Neighbour];
                Father[Neighbour] = Node;

                if(!inQueue[Neighbour]) {
                    Queue.push(Neighbour);
                    inQueue[Neighbour] = true;
                    }

            }

        }

    return (Distance[Destination] != oo);

}
void buildFlowNetwork() {

    int i;

    Source = 0;
    Destination = N + M + 1;

    for(i = 1; i <= N; i++) {
        Graph[Source].pb(i);
        Capacity[Source][i] = true;
        }

    for(i = N + 1; i < Destination; i++) {
        Graph[i].pb(Destination);
        Capacity[i][Destination] = true;
        }

}
void Solve() {

    int i, j, minFlow, Node;
    buildFlowNetwork();

    while(bellmanFord()) {

        minFlow = oo;

        for(Node = Destination; Node != Source; Node = Father[Node])
            Capacity[Father[Node]][Node] = false,
            Capacity[Node][Father[Node]] = true;

        minCost += Distance[Destination];

        }

    for(i = 1; i <= N; i++)
        for(j = N + 1; j < Destination; j++)
            if(!Capacity[i][j] && Edge[i][j]) {
                Solution.pb(Edge[i][j]);
                break;
                }

}
void Read() {

    int i, x, y, cost, E;
    ifstream in("cmcm.in");
    in >> N >> M >> E;

    for(i = 1; i <= E; i++) {

        in >> x >> y >> cost;

        y += N;

        Graph[x].pb(y);
        Graph[y].pb(x);

        Cost[x][y] = cost;
        Cost[y][x] = -cost;

        Capacity[x][y] = true;
        Edge[x][y] = i;

        }

    in.close();

}
void Write() {

    ofstream out("cmcm.out");
    out << Solution.size() << ' ' << minCost << '\n';

    for(int i = 0; i < Solution.size(); i++)
        out << Solution[i] << ' ';

    out << '\n';
    out.close();

}
int main() {

    Read();
    Solve();
    Write();

    return 0;

}