Cod sursa(job #3328059)

Utilizator brianabucur11Briana Bucur brianabucur11 Data 6 decembrie 2025 08:53:26
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.86 kb
#include <bits/stdc++.h>

using namespace std;

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

const int inf = 1e9;

vector <int> g[705];

vector <pair <int, int>> edges;

int n, s, dest;

int cost[705][705], cap[705][705];

int d[705];

queue <int> q;

void bellman(int s, int dest)
{
    for (int i = 0; i <= n + 1; i++)
        d[i] = inf;
    d[s] = 0;
    q.push(s);
    while (!q.empty())
    {
        int node = q.front();
        q.pop();
        for (auto it : g[node])
            if (cap[node][it] && d[it] > d[node] + cost[node][it])
            {
                d[it] = d[node] + cost[node][it];
                q.push(it);
            }
    }
}

typedef pair <int, int> pi;

priority_queue <pi, vector <pi>, greater <pi>> pq;

int dist[705], dt[705], t[705];
bool sel[705];

bool dijkstra (int s, int dest)
{
    for (int i = 0; i <= n + 1; i++)
    {
        dt[i] = dist[i] = inf;
        sel[i] = false;
        t[i] = 0;
    }
    while (!pq.empty ())
        pq.pop ();
    dt[s] = 0;
    dist[s] = 0;
    pq.push ({0, s});
    while (!pq.empty ())
    {
        int k = pq.top().second;
        pq.pop();
        if (sel[k])
            continue;
        sel[k] = true;
        for (auto i : g[k])
        {
            if (cap[k][i] > 0)
            {
                int val = dt[k] + cost[k][i] + d[k] - d[i];
                if (dt[i] > val)
                {
                    dt[i] = val;
                    dist[i] = dist[k] + cost[k][i];
                    t[i] = k;
                    pq.push ({val, i});
                }
            }
        }
    }
    return sel[dest];
}

int max_flow (int s, int dest)
{
    int rez = 0;
    bellman (s, dest);
    while (dijkstra (s, dest))
    {
        for (int i = 0; i <= n + 1; i++)
            d[i] = dist[i];
        rez += d[dest];
        for (int i = dest; i != s; i = t[i])
        {
            cap[t[i]][i]--;
            cap[i][t[i]]++;
        }
    }
    return rez;
}

void add_edge (int x, int y, int c)
{
    g[x].push_back(y);
    g[y].push_back(x);

    cost[x][y] = c;
    cost[y][x] = -c;

    cap[x][y] = 1;
}

int main ()
{
    int l, r, e;
    fin >> l >> r >> e;
    for (int i = 1; i <= e; i++)
    {
        int x, y, c;
        fin >> x >> y >> c;
        add_edge(x,y + l,c);
        edges.push_back({x, y + l});
    }
    n = l + r;
    s = 0, dest = n + 1;

    for (int i = 1; i <= l; i++)
        add_edge(0,i,0);
    for (int i = l + 1; i <= n; i++)
        add_edge(i,dest,0);

    int rez = max_flow(s,dest);
    vector <int> sol;
    for (int i = 0; i < e; i++)
        if (!cap[edges[i].first][edges[i].second])
            sol.push_back(i + 1);
    fout << sol.size() << " " << rez << '\n';
    for (auto it : sol)
        fout << it << " ";
    return 0;
}