Cod sursa(job #1362787)

Utilizator Stefex09Stefan Teodorescu Stefex09 Data 26 februarie 2015 15:29:01
Problema Cuplaj maxim de cost minim Scor 60
Compilator cpp Status done
Runda Arhiva educationala Marime 2.66 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <cstring>
#include <queue>

using namespace std;

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

const int MAXN = 2 * 310;
const int INF = 0x3f3f3f3f;
typedef pair <int, int> PII;

int S, D;
vector <PII> Graf[MAXN];
queue <int> Q;
int Edge[MAXN][MAXN];
int C[MAXN][MAXN], F[MAXN][MAXN];
bool Viz[MAXN];
int T[MAXN];
int Best[MAXN];

bool BF ()
{
    memset (Viz, 0, sizeof (Viz));
    memset (Best, 0x3f, sizeof (Best));

    Q.push (S);
    Best[S] = 0;
    Viz[S] = 1;

    int nod;
    vector <PII> :: iterator it;

    while (!Q.empty ()){
        nod = Q.front ();
        Q.pop ();
        Viz[nod] = 0;

        for (it = Graf[nod].begin (); it != Graf[nod].end (); ++ it)
            if (F[nod][it -> first] < C[nod][it -> first])
                if (Best[it -> first] > Best[nod] + (it -> second)){
                    Best[it -> first] = Best[nod] + (it -> second);
                    T[it -> first] = nod;

                    if (!Viz[it -> first]){
                        Viz[it -> first] = 1;
                        Q.push (it -> first);
                    }
                }
    }

    return (Best[D] != INF);
}

inline void getmin (int &A, const int &B)
{
    if (B < A)
        A = B;
}

int main()
{
    int N, M, E, a, b, c, i, j;

    in >> N >> M >> E;
    S = 0;
    D = N + M + 1;
    for (i = 1; i <= E; i ++){
        in >> a >> b >> c;
        Edge[a][b + N] = i;

        Graf[a].push_back (make_pair (b + N, c));
        Graf[b + N].push_back (make_pair (a, -c));
        C[a][b + N]  = 1;
    }

    for (i = 1; i <= N; i ++){
        Graf[S].push_back (make_pair (i, 0));
        C[S][i] = 1;
    }
    for (i = 1; i <= M; i ++){
        Graf[i + N].push_back (make_pair (D, 0));
        C[i + N][D] = 1;
    }

    int flow = 0;
    int fm;
    while (BF ()){
        fm = INF;

        for (i = D; i != S; i = T[i])
            getmin (fm, C[T[i]][i] - F[T[i]][i]);

        if (fm == 0)
            continue;

        for (i = D; i != S; i = T[i]){
            F[T[i]][i] += fm;
            F[i][T[i]] -= fm;
        }

        flow += fm * Best[D];
    }

    int Cuplaj = 0;

    for (i = 1; i <= N; i ++)
        for (j = 1; j <= M; j ++)
            if (F[i][j + N] == C[i][j + N]){
                Cuplaj ++;
                break;
            }

    out << Cuplaj << " " << flow << "\n";

    for (i = 1; i <= N; i ++)
        for (j = 1; j <= M; j ++)
            if (F[i][j + N]){
                out << Edge[i][j + N] << " ";
                break;
            }

    return 0;
}