Cod sursa(job #3303997)

Utilizator unomMirel Costel unom Data 19 iulie 2025 17:10:13
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.71 kb
#include <fstream>
#include <vector>
#include <queue>
#include <iostream>

using namespace std;

struct edge
{
    int cap, cost, initial;
};

ifstream in("cmcm.in");
ofstream out("cmcm.out");
int nst, ndr, m, cntedge, cntnod, source, dest;
int max_flow, min_cost;
vector<pair<int, int>> v[1255];
edge muc[200005];
int inv[200005];
int init_cost[1255];
int in_queue[1255];
int cost[1255];
pair<int, int> from[1255];
int INF = (1 << 30);

void add_edge(int a, int b, int cap, int cost, int initial)
{
    cntedge++;
    muc[cntedge] = {cap, cost, initial};
    v[a].push_back({b, cntedge});

    cntedge++;
    muc[cntedge] = {0, -cost, 0};
    v[b].push_back({a, cntedge});

    inv[cntedge - 1] = cntedge;
    inv[cntedge] = cntedge - 1;
}

void bellman_ford()
{
    queue<int> q;
    for(int i = 1; i<=cntnod; i++)
    {
        init_cost[i] = 0;
        in_queue[i] = 1;
        q.push(i);
    }

    while(!q.empty())
    {
        int nod = q.front();

        q.pop();
        in_queue[nod] = 0;

        for(auto it: v[nod])
        {
            if(muc[it.second].cap > 0 && init_cost[nod] + muc[it.second].cost < init_cost[it.first])
            {
                init_cost[it.first] = init_cost[nod] + muc[it.second].cost;

                if(in_queue[it.first] == 0)
                {
                    in_queue[it.first] = 1;
                    q.push(it.first);
                }
            }
        }
    }
}

int dijkstra()
{
    for(int i = 1; i<=cntnod; i++)
    {
        cost[i] = INF;
        from[i] = {0, 0};
    }

    cost[source] = 0;
    priority_queue<pair<int, int>> pq;
    pq.push({0, source});

    while(!pq.empty())
    {
        //cout<<"b";
        int d = -pq.top().first;
        int nod = pq.top().second;

        pq.pop();

        if(d != cost[nod])
        {
            continue;
        }

        for(auto it: v[nod])
        {
            if(muc[it.second].cap > 0 && d + muc[it.second].cost + init_cost[nod] - init_cost[it.first] < cost[it.first])
            {
                cost[it.first] = d + muc[it.second].cost + init_cost[nod] - init_cost[it.first];
                from[it.first] = {nod, it.second};

                pq.push({-cost[it.first], it.first});
            }
        }
    }

    return (cost[dest] != INF);
}

int main()
{
    in>>nst>>ndr>>m;

    int x, y, z;
    for(int i = 1; i<=m; i++)
    {
        in>>x>>y>>z;

        add_edge(x, y + nst, 1, z, i);
    }

    cntnod = nst + ndr;

    cntnod++;
    source = cntnod;

    cntnod++;
    dest = cntnod;

    for(int i = 1; i<=nst; i++)
    {
        add_edge(source, i, 1, 0, 0);
    }

    for(int i = nst + 1; i<=nst + ndr; i++)
    {
        add_edge(i, dest, 1, 0, 0);
    }

    bellman_ford();

    while(dijkstra())
    {
        for(int i = 1; i<=cntnod; i++)
        {
            if(cost[i] != INF)
            {
                init_cost[i] += cost[i];
            }
        }

        int flux = INF;
        int nod = dest;
        while(nod != source)
        {
            flux = min(flux, muc[from[nod].second].cap);

            nod = from[nod].first;
        }

        max_flow += flux;
        min_cost += flux * init_cost[dest];

        nod = dest;
        while(nod != source)
        {
            muc[from[nod].second].cap -= flux;
            muc[inv[from[nod].second]].cap += flux;

            nod = from[nod].first;
        }
    }

    out<<max_flow<<" "<<min_cost<<'\n';

    for(int i = 1; i<=cntedge; i++)
    {
        if(muc[i].initial != 0 && muc[i].cap == 0)
        {
            out<<muc[i].initial<<" ";
        }
    }

    return 0;
}