Cod sursa(job #2884275)

Utilizator alex_braslasuBraslasu Alexandru alex_braslasu Data 2 aprilie 2022 19:49:49
Problema Cuplaj maxim de cost minim Scor 50
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.41 kb
#include <fstream>
#include <vector>
#include <queue>

using namespace std;

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

const int INF = (1LL << 31) - 1;
int n, m, e, x, y, i, j, S, D, lg, nod, costmin, cnt, ok[310], TOTAL;
int T[310], muchie[310][310], cost[310][310], c[310][310], f[310][310], drum[310];
vector<int > G[310];
queue<int > q;
struct cmp
{
    bool operator()(int x, int y)
    {
        return drum[x] < drum[y];
    }
};
priority_queue<int, vector<int >, cmp > h;

static inline void BellmanFord()
{
    for (int i = 1; i <= lg; ++i)
        ok[i] = 0, drum[i] = INF;
    drum[S] = 0;
    ok[S] = 1;
    q.push(S);
    while (!q.empty())
    {
        int nod = q.front();
        ok[nod] = 0;
        q.pop();
        for (auto it : G[nod])
            if (c[nod][it] > f[nod][it] && drum[nod] + cost[nod][it] < drum[it])
            {
                drum[it] = drum[nod] + cost[nod][it];
                if (!ok[it])
                {
                    ok[it] = 1;
                    q.push(it);
                }
            }
    }
    TOTAL = drum[D];
}

static inline int Dijkstra()
{
    for (int i = 1; i <= lg; ++i)
        if (drum[i] != INF)
            for (auto it : G[i])
                if (drum[it] != INF)
                    cost[i][it] += drum[i] - drum[it];
    for (int i = 1; i <= lg; ++i)
        ok[i] = 0, drum[i] = INF, T[i] = 0;
    drum[S] = 0;
    ok[S] = 1;
    h.push(S);
    while (!h.empty())
    {
        int nod = h.top();
        ok[nod] = 0;
        h.pop();
        for (auto it : G[nod])
            if (c[nod][it] > f[nod][it] && drum[nod] + cost[nod][it] < drum[it])
            {
                T[it] = nod;
                drum[it] = drum[nod] + cost[nod][it];
                if (!ok[it])
                {
                    ok[it] = 1;
                    h.push(it);
                }
            }
    }
    if (drum[D] != INF)
        return 1;
    return 0;
}

int main()
{
    ios::sync_with_stdio(false);
    fin.tie(nullptr);
    fin >> n >> m >> e;
    for (i = 1; i <= e; ++i)
    {
        fin >> x >> y;
        ++x, y = n + y + 1;
        fin >> cost[x][y];
        cost[y][x] = -cost[x][y];
        G[x].push_back(y);
        G[y].push_back(x);
        muchie[x][y] = i;
        c[x][y] = 1;
    }
    S = 1; D = lg = n + m + 2;
    for (i = 2; i <= n + 1; ++i)
    {
        G[S].push_back(i);
        c[S][i] = 1;
    }
    for (i = n + 2; i <= n + m + 1; ++i)
    {
        G[i].push_back(D);
        c[i][D] = 1;
    }
    BellmanFord();
    while (Dijkstra())
    {
        int flux = INF;
        int nod = D;
        while (nod != S)
        {
            if (c[T[nod]][nod] - f[T[nod]][nod] < flux)
                flux = c[T[nod]][nod] - f[T[nod]][nod];
            nod = T[nod];
        }
        nod = D;
        while (nod != S)
        {
            f[T[nod]][nod] += flux;
            f[nod][T[nod]] -= flux;
            nod = T[nod];
        }
        TOTAL += drum[D];
        costmin += flux * TOTAL;
    }
    for (i = 2; i <= n + 1; ++i)
        for (j = n + 2; j <= lg; ++j)
            if (f[i][j] && c[i][j])
                ++cnt;
    fout << cnt << " " << costmin << '\n';
    for (i = 2; i <= n + 1; ++i)
        for (j = n + 2; j <= lg; ++j)
           if (f[i][j] && c[i][j])
               fout << muchie[i][j] << " ";
    return 0;
}