Cod sursa(job #2931588)

Utilizator toma_ariciuAriciu Toma toma_ariciu Data 31 octombrie 2022 16:29:41
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.48 kb
#include <fstream>
#include <iostream>
#include <vector>
#include <queue>

using namespace std;

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

const int maxN = 605, inf = 0x3f3f3f3f;
int n, m, sursa, dest;
int fake_dist[maxN], real_dist[maxN], prv[maxN], max_flow, total_cost, dist[maxN];
bool used[maxN];
struct muchie {
    int nxt, flux, cap, cost;
}lm[110005];
vector <int> G[maxN];
struct haha4heap {
    int nod, cost;
    bool operator < (const haha4heap &other) const {
        return cost > other.cost;
    }
};
priority_queue <haha4heap> heap;
queue <int> q;

void bellman_ford()
{
    for(int i = sursa; i <= dest; i++)
        dist[i] = inf;
    dist[sursa] = 0;
    q.push(sursa);
    while(!q.empty())
    {
        int curr = q.front();
        q.pop();
        for(int ind : G[curr])
        {
            muchie aux = lm[ind];
            if(aux.cap == 0 || dist[curr] + aux.cost >= dist[aux.nxt])
                continue;
            dist[aux.nxt] = dist[curr] + aux.cost;
            q.push(aux.nxt);
        }
    }
}


bool dijkstra()
{
    for(int i = sursa; i <= dest; i++)
    {
        fake_dist[i] = inf;
        real_dist[i] = dist[i];
        used[i] = 0;
    }
    while(!heap.empty())
        heap.pop();
    fake_dist[sursa] = 0;
    dist[sursa] = 0;
    heap.push({sursa, 0});
    while(!heap.empty())
    {
        int curr = heap.top().nod;
        heap.pop();
        if(used[curr])
            continue;
        used[curr] = 1;
        for(int ind : G[curr])
        {
            muchie aux = lm[ind];
            if(aux.flux < aux.cap && fake_dist[curr] + aux.cost + real_dist[curr] - real_dist[aux.nxt] < fake_dist[aux.nxt])
            {
                prv[aux.nxt] = ind;
                fake_dist[aux.nxt] = fake_dist[curr] + aux.cost + real_dist[curr] - real_dist[aux.nxt];
                dist[aux.nxt] = dist[curr] + aux.cost;
                heap.push({aux.nxt, fake_dist[aux.nxt]});
            }
        }
    }
    if(fake_dist[dest] == inf)
        return 0;
    return 1;
}

int main()
{
    int n2;
    fin >> n >> n2 >> m;
    for(int i = 0; i < m; i++)
    {
        int x, y, cst;
        fin >> x >> y >> cst;
        y += n;
        lm[2 * i] = {y, 0, 1, cst};
        lm[2 * i + 1] = {x, 0, 0, -cst};
        G[x].push_back(2 * i);
        G[y].push_back(2 * i + 1);
    }
    sursa = 0;
    dest = n + n2 + 1;
    for(int i = m; i < m + n; i++)
    {
        lm[2 * i] = {i - m + 1, 0, 1, 0};
        lm[2 * i + 1] = {sursa, 0, 0, 0};
        G[sursa].push_back(2 * i);
        G[i - m + 1].push_back(2 * i + 1);
    }
    for(int i = m + n; i < m + n + n2; i++)
    {
        lm[2 * i] = {dest, 0, 1, 0};
        lm[2 * i + 1] = {i - m + 1, 0, 0, 0};
        G[i - m + 1].push_back(2 * i);
        G[dest].push_back(2 * i + 1);
    }
    bellman_ford();
    while(dijkstra())
    {
        int min_flow = inf;
        for(int x = dest; x != sursa; x = lm[prv[x] ^ 1].nxt)
            min_flow = min(min_flow, lm[prv[x]].cap - lm[prv[x]].flux);
        for(int x = dest; x != sursa; x = lm[prv[x] ^ 1].nxt)
        {
            lm[prv[x]].flux += min_flow;
            lm[prv[x] ^ 1].flux -= min_flow;
        }
        total_cost += min_flow * dist[dest];
        max_flow += min_flow;
    }
    fout << max_flow << ' ' << total_cost << '\n';
    for(int i = 0; i < m; i++)
        if(lm[2 * i].flux == 1)
            fout << i + 1 << ' ';
    return 0;
}