Cod sursa(job #2875494)

Utilizator beingsebiPopa Sebastian beingsebi Data 21 martie 2022 18:55:26
Problema Cuplaj maxim de cost minim Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.31 kb
#include <bits/stdc++.h>
using namespace std;
ifstream f("cmcm.in");
ofstream g("cmcm.out");
// #define f cin
// #define g cout
const int nmax = 352;
vector<int> v[nmax];
int cap[nmax][nmax], we[nmax][nmax];
int c1, c2, m, source, sink, final_cost, potential[nmax], dp[nmax], realc[nmax], pre[nmax], mc[nmax][nmax];
queue<int> q;
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;
vector<bool> inq(nmax, false);
void bellman_ford();
bool dijkstra();
vector<int> rez;
int32_t main()
{
    f >> c1 >> c2 >> m;
    source = c1 + c2 + 1;
    sink = c1 + c2 + 2;
    for (int x, y, t = 1; t <= m; t++)
    {
        f >> x >> y >> we[x][y + c1];
        mc[x][y + c1] = t;
        cap[x][y + c1] = 1;
        v[x].push_back(y + c1);
        v[y + c1].push_back(x);
        we[y + c1][x] = -we[x][y + c1];
    }
    for (int i = 1; i <= c1; i++)
    {
        cap[source][i] = 1;
        v[source].push_back(i);
        v[i].push_back(source);
    }
    for (int i = 1; i <= c2; i++)
    {
        cap[i + c1][sink] = 1;
        v[i + c1].push_back(sink);
        v[sink].push_back(i + c1);
    }
    bellman_ford();
    while (dijkstra())
        ;
    for (int i = 1; i <= c1; i++)
        for (int j = c1 + 1; j <= c1 + c2; j++)
            if (!cap[i][j] && we[i][j])
            {
                break;
                rez.push_back(mc[i][j]);
            }
    g << rez.size() << ' ' << final_cost << '\n';
    for (auto i : rez)
        g << i << " ";
    return 0;
}
void bellman_ford()
{
    memset(potential, 0x3f3f3f3f, sizeof potential);

    q.push(source);
    potential[source] = 0;
    inq[source] = 1;

    while (!q.empty())
    {
        static int ac, nc;
        ac = q.front();
        inq[ac] = 0;
        q.pop();
        for (const int &i : v[ac])
            if (cap[ac][i])
            {
                nc = potential[ac] + we[ac][i];
                if (nc < potential[i])
                {
                    potential[i] = nc;
                    if (inq[i])
                        continue;
                    inq[i] = 1;
                    q.push(i);
                }
            }
    }
}
bool dijkstra()
{
    memset(dp, 0x3f3f3f3f, sizeof dp);
    realc[source] = dp[source] = 0;
    pq.push({0, source});
    while (!pq.empty())
    {
        static int nod, cst, ne;
        nod = pq.top().second;
        cst = pq.top().first;
        pq.pop();
        if (cst != dp[nod])
            continue;
        for (const int &i : v[nod])
            if (cap[nod][i])
            {
                ne = dp[nod] + we[nod][i] + potential[nod] - potential[i];
                if (ne < dp[i])
                {
                    dp[i] = ne;
                    realc[i] = realc[nod] + we[nod][i];
                    pre[i] = nod;
                    pq.push({ne, i});
                }
            }
    }
    if (dp[sink] == (0x3f3f3f3f))
        return 0;
    memcpy(potential, realc, sizeof potential);
    int mnm = INT_MAX;
    for (int ax = sink; ax != source; ax = pre[ax])
        mnm = min(mnm, cap[pre[ax]][ax]);
    final_cost += mnm * realc[sink];
    for (int ax = sink; ax != source; ax = pre[ax])
    {
        cap[pre[ax]][ax] -= mnm;
        cap[ax][pre[ax]] += mnm;
    }
    return 1;
}