Cod sursa(job #2550118)

Utilizator Mihai145Oprea Mihai Adrian Mihai145 Data 18 februarie 2020 14:28:26
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.59 kb
#include <fstream>
#include <vector>
#include <queue>

using namespace std;

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

const int NMAX = 2 * 300;
const int INF = 10000000;

int sizeL, sizeR, M;
int S, D;

vector <int> g[NMAX + 5];

int mch[NMAX + 5][NMAX + 5];

int capacity[NMAX + 5][NMAX + 5], flow[NMAX + 5][NMAX + 5];
int cost[NMAX + 5][NMAX + 5];

int costTo[NMAX + 5], pumpFlow[NMAX + 5];
int bef[NMAX + 5];

bool seen[NMAX + 5];

bool BellmanFord()
{
    for(int i = S; i <= D; i++)
        costTo[i] = INF, pumpFlow[i] = INF;

    queue <int> Q;

    Q.push(S);
    costTo[S] = 0;
    seen[S] = 1;

    while(!Q.empty())
    {
        int node = Q.front();
        Q.pop();

        seen[node] = 0;

        for(auto it : g[node])
            if(flow[node][it] < capacity[node][it])
                if(costTo[it] > costTo[node] + cost[node][it])
                {
                    costTo[it] = costTo[node] + cost[node][it];
                    bef[it] = node;

                    pumpFlow[it] = min(pumpFlow[node], capacity[node][it] - flow[node][it]);

                    if(!seen[it])
                    {
                        seen[it] = 1;
                        Q.push(it);
                    }
                }
    }

    return costTo[D] != INF;
}

int main()
{
    fin >> sizeL >> sizeR >> M;

    for(int i = 1; i <= M; i++)
    {
        int x, y, cst;
        fin >> x >> y >> cst;

        mch[x][y + sizeL] = i;
        mch[y + sizeL][x] = i;

        g[x].push_back(y + sizeL);
        g[y + sizeL].push_back(x);

        capacity[x][y + sizeL] = 1;

        cost[x][y + sizeL] = cst;
        cost[y + sizeL][x] = -cst;
    }

    S = 0, D = sizeL + sizeR + 1;

    for(int i = 1; i <= sizeL; i++)
    {
        g[S].push_back(i);
        g[i].push_back(S);

        capacity[S][i] = 1;
    }

    for(int i = 1; i <= sizeR; i++)
    {
        g[i + sizeL].push_back(D);
        g[D].push_back(i + sizeL);

        capacity[i + sizeL][D] = 1;
    }

    int maxFlow = 0, minCost = 0;

    while(BellmanFord())
    {
        for(int i = D; i != S; i = bef[i])
        {
            flow[bef[i]][i] += pumpFlow[D];
            flow[i][bef[i]] -= pumpFlow[D];
        }

        maxFlow += pumpFlow[D];
        minCost += pumpFlow[D] * costTo[D];
    }

    fout << maxFlow << ' ' << minCost << '\n';

    for(int i = 1; i <= sizeL; i++)
        for(int j = 1; j <= sizeR; j++)
            if(flow[i][j + sizeL] == 1)
                fout << mch[i][j + sizeL] << ' ';

    return 0;
}