Cod sursa(job #2695630)

Utilizator popabogdanPopa Bogdan Ioan popabogdan Data 13 ianuarie 2021 23:52:24
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.5 kb
#include <bits/stdc++.h>

#define N_MAX 305
#define INF 1100000000

using namespace std;

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

int N, M, E;
vector <int> G[2 * N_MAX];
int T[2 * N_MAX];
int C[2 * N_MAX][2 * N_MAX];
int F[2 * N_MAX][2 * N_MAX];
int Cost[2 * N_MAX][2 * N_MAX];
int dist[2 * N_MAX];
bool inQ[2 * N_MAX];
queue <int> Q;
int idx[2 * N_MAX][2 * N_MAX];

bool BF(int start, int finish)
{
    for(int i = 0; i <= N; i++) {
        T[i] = -1;
    }
    for(int i = 0; i <= N; i++) {
        dist[i] = INF;
    }

    T[start] = start;
    dist[start] = 0;
    Q.push(start);
    inQ[start] = true;

    while(!Q.empty())
    {
        int node = Q.front();
        inQ[node] = false;
        Q.pop();
        for(auto it : G[node])
            if(dist[it] > dist[node] + Cost[node][it] && C[node][it] > F[node][it])
            {
                dist[it] = dist[node] + Cost[node][it];
                T[it] = node;
                if(!inQ[it]) {
                    inQ[it] = true;
                    Q.push(it);
                }
            }
    }
    return T[finish] != -1;
}

pair <int, int> maxFlow(int start, int finish)
{
    pair <int, int> ret;
    memset(F, 0, sizeof(F));
    while(BF(start, finish))
    {
        int add = INF;
        for(int node = finish; node != start; node = T[node])
            add = min(add, C[T[node]][node] - F[T[node]][node]);
        ret.first += add;
        for(int node = finish; node != start; node = T[node]) {
            ret.second += Cost[T[node]][node] * add;
            F[T[node]][node] += add;
            F[node][T[node]] -= add;
        }
    }
    return ret;
}



int main()
{
    fin >> N >> M >> E;
    for(int i = 1; i <= E; i++) {
        int p, q, c;
        fin >> p >> q >> c;
        C[p][N + q] = 1;
        Cost[p][N + q] = c;
        Cost[N + q][p] = -c;
        G[p].push_back(N + q);
        idx[p][N + q] = i;
        G[N + q].push_back(p);
    }

    for(int i = 1; i <= N; i++) {
        G[0].push_back(i);
        C[0][i] = 1;
    }

    for(int i = 1; i <= M; i++) {
        G[N + i].push_back(N + M + 1);
        C[N + i][N + M + 1] = 1;
    }

    N += M + 1;
    auto ans = maxFlow(0, N);
    fout << ans.first << " " << ans.second << "\n";

    for(int i = 1; i <= N; i++) {
        for(auto it : G[i]) {
            if(F[i][it] == 1 && idx[i][it] != 0) {
                fout << idx[i][it] << " ";
            }
        }
    }
    return 0;
}