Cod sursa(job #1578024)

Utilizator retrogradLucian Bicsi retrograd Data 24 ianuarie 2016 04:40:34
Problema Cuplaj maxim de cost minim Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 3.53 kb
#include <iostream>
#include <queue>
#include <cstring>
#include <cstdio>

using namespace std;

void Read(int &a) {
    char c, sgn = 0;

    for(c = getchar(); !isdigit(c) && c != '-'; c = getchar());
    if(c == '-') sgn = 0, c = getchar();

    for(a = 0; isdigit(c); c = getchar())
        a = (a << 1) + (a << 3) + c - '0';
    if(sgn) a = -a;
}

struct Flow {
    const static int MAX_EDGES = 100000;
    const static int MAX_NODES = 1005;
    const int INF = 1e9 + 50;

    int S = MAX_NODES - 2, D = MAX_NODES - 1;

    int G[MAX_NODES];
    struct Edge {
        int vec, flow, cap, cost, rev, nxt;
    };
    Edge E[MAX_EDGES];
    int edges = 0;

    int ParentNode[MAX_NODES], ParentEdge[MAX_NODES], Dist[MAX_NODES];
    bool InQ[MAX_NODES];
    queue<int> Q;

    Flow() {
        Reset();
    }

    void setSource(int s) {
        S = s;
    }
    void setSink(int d) {
        D = d;
    }

    void _addEdge(int a, int b, int cap, int cost, int rev) {
        ++edges;
        E[edges] = (Edge) {b, 0, cap, cost, rev, G[a]};
        G[a] = edges;
    }
    void AddEdge(int a, int b, int cap, int cost) {
        _addEdge(a, b, cap, cost, edges + 2);
        _addEdge(b, a, 0, -cost, edges);
    }

    bool Bellman() {
        memset(ParentNode, 0, sizeof(ParentNode));

        Dist[S] = 0;
        Q.push(S);


        while(!Q.empty()) {
            int top = Q.front();
            InQ[top] = 0;
            Q.pop();

            for(int i=G[top]; i; i=E[i].nxt) {
                int vec = E[i].vec;
                if(E[i].flow < E[i].cap && (ParentNode[vec] == 0 || Dist[vec] > Dist[top] + E[i].cost)) {
                    Dist[vec] = Dist[top] + E[i].cost;
                    ParentNode[vec] = top;
                    ParentEdge[vec] = i;

                    if(!InQ[vec]) {
                        Q.push(vec);
                        InQ[vec] = 1;
                    }
                }
            }
        }

        return ParentNode[D] != 0;
    }

    void Reset() {
        edges = 0;
        memset(G, 0, sizeof(G));
    }

    pair<int, int> MFMC() {
        int cost = 0, flow = 0;

        while(Bellman()) {
            int M = INF;

            for(int node = D; node != S; node = ParentNode[node]) {
                int ei = ParentEdge[node];
                M = min(M, E[ei].cap - E[ei].flow);
            }

            for(int node = D; node != S; node = ParentNode[node]) {
                int ei = ParentEdge[node],
                    ri = E[ei].rev;

                E[ei].flow += M;
                E[ri].flow -= M;

                cost += E[ei].cost * M;
            }

            flow += M;
        }

        return {flow, cost};
    }

};
Flow F;

int Ind[200000];

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

    int n, m, e;
    Read(n); Read(m); Read(e);

    #define Left(i) 2*i
    #define Right(i) 2*i+1

    for(int i=1; i<=n; i++)
        F.AddEdge(F.S, Left(i), 1, 0);
    for(int i=1; i<=m; i++)
        F.AddEdge(Right(i), F.D, 1, 0);

    int a, b, c;
    for(int i=1; i<=e; i++) {
        Read(a); Read(b); Read(c);

        Ind[F.edges+1] = Ind[F.edges+2] = i;
        F.AddEdge(Left(a), Right(b), 1, c);
    }

    auto ret = F.MFMC();
    cout << ret.first << " " << ret.second << '\n';

    for(int i=1; i<=F.edges; i++) {
        if(F.E[i].flow > 0 && Ind[i] > 0) {
            cout << Ind[i] << " ";
        }
    }

    return 0;
}