Cod sursa(job #2637677)

Utilizator Mihai145Oprea Mihai Adrian Mihai145 Data 24 iulie 2020 08:48:33
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.35 kb
#include <fstream>
#include <vector>
#include <queue>

using namespace std;

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

const int NMAX = 300;
const int INF = 1e6;

int N, M, E, S, D;

vector <int> g[2 * NMAX + 5];
int cost[2 * NMAX + 5][2 * NMAX + 5], mch[2 * NMAX + 5][2 * NMAX + 5];
int cap[2 * NMAX + 5][2 * NMAX + 5], flow[2 * NMAX + 5][2 * NMAX + 5];

int flowTo[2 * NMAX + 5], costTo[2 * NMAX + 5], bef[2 * NMAX + 5];
bool inQ[2 * NMAX + 5];

bool Dijkstra()
{
    for(int i = 0; i <= N + M + 1; i++)
        flowTo[i] = costTo[i] = INF;

    queue <int> Q;
    Q.push(S);
    inQ[S] = true;

    costTo[S] = 0;

    while(!Q.empty())
    {
        int node = Q.front();
        Q.pop();
        inQ[node] = false;

        for(auto it : g[node])
            if(flow[node][it] < cap[node][it])
                if(costTo[it] > costTo[node] + cost[node][it])
                {
                    flowTo[it] = min(flowTo[node], cap[node][it] - flow[node][it]);
                    costTo[it] = costTo[node] + cost[node][it];
                    bef[it] = node;

                    if(!inQ[it])
                    {
                        Q.push(it);
                        inQ[it] = true;
                    }
                }
    }

    return flowTo[D] != INF;
}

int main()
{
    cin >> N >> M >> E;

    for(int i = 1; i <= E; i++)
    {
        int x, y, c;
        cin >> x >> y >> c;

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

        mch[x][y + N] = i;
        cost[x][y + N] = c;
        cost[y + N][x] = -c;
        cap[x][y + N] = 1;
    }

    S = 0, D = N + M + 1;

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

        cap[S][i] = 1;
    }

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

        cap[i + N][D] = 1;
    }

    int maxFlo = 0, minCost = 0;

    while(Dijkstra())
    {
        for(int node = D; node != S; node = bef[node])
        {
            flow[bef[node]][node] += flowTo[D];
            flow[node][bef[node]] -= flowTo[D];
        }

        maxFlo += flowTo[D];
        minCost += flowTo[D] * costTo[D];
    }

    cout << maxFlo << ' ' << minCost << '\n';

    for(int i = 1; i <= N; i++)
        for(int j = 1; j <= M; j++)
            if(flow[i][j + N] == 1)
                cout << mch[i][j + N] << ' ';

    return 0;
}