Cod sursa(job #3290779)

Utilizator Radu_MocanasuMocanasu Radu Radu_Mocanasu Data 31 martie 2025 20:45:01
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.5 kb
#include <bits/stdc++.h>

using namespace std;

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

const int inf = 0x3f3f3f3f;

struct MIN_COST_FLOW{

    vector < vector <int> > G;
    int d[605];
    int t[605];

    int pot[605];
    int pot2[605];

    bitset <605> in_queue;
    bitset <605> viz;
    queue <int> q;

    int n;

    int c[605][605];
    int w[605][605];
    int poz[301][301];

    set < pair <int, int> > s;

    MIN_COST_FLOW() {}

    void add_edge(int x, int y, int _c, int _w){
        G[x].push_back(y);
        c[x][y] = _c;
        w[x][y] = _w;
    }

    void bellman_ford(){
        memset(pot, 0x3f, sizeof pot);
        memset(t, 0, sizeof t);
        q.push(0);
        pot[0] = 0;
        in_queue[0] = 1;
        while(!q.empty()){
            int nod = q.front();
            q.pop();
            in_queue[nod] = 0;
            for(auto x : G[nod]){
                if(c[nod][x] > 0 && pot[x] > pot[nod] + w[nod][x]){
                    pot[x] = pot[nod] + w[nod][x];
                    t[x] = nod;
                    if(!in_queue[x]){
                        q.push(x);
                        in_queue[x] = 1;
                    }
                }
            }
        }
    }

    int dijkstra(){
        memset(d, 0x3f, sizeof d);
        memset(t, 0, sizeof t);
        pot2[0] = d[0] = 0;
        s.insert({0, 0});
        viz.reset();
        while(!s.empty()){
            auto it = s.begin();
            int nod = it->second;
            s.erase(it);
            if(viz[nod]) continue;
            viz[nod] = 1;
            for(auto x : G[nod]){
                if(c[nod][x] > 0 && d[x] > d[nod] + w[nod][x] + pot[nod] - pot[x]){
                    d[x] = d[nod] + w[nod][x] + pot[nod] - pot[x];
                    pot2[x] = pot2[nod] + w[nod][x];
                    t[x] = nod;
                    s.insert({d[x], x});
                }
            }
        }
        for(int i = 0; i <= n; i++) pot[i] = pot2[i];
        return d[n];
    }

    pair <int, int> edmonds_karp(){
        int max_flow = 0, rez = 0;
        while(dijkstra() != inf){
            int new_flow = 1e9;
            for(int temp = n; temp; temp = t[temp]) new_flow = min(new_flow, c[t[temp]][temp]);
            for(int temp = n; temp; temp = t[temp]){
                c[t[temp]][temp] -= new_flow;
                c[temp][t[temp]] += new_flow;
                rez += new_flow * w[t[temp]][temp];
            }
            max_flow += new_flow;
        }
        return {max_flow, rez};
    }

};

MIN_COST_FLOW cuplaj;

int main()
{
    int n,i,m,k,x,y;
    fin >> n >> m >> k;
    cuplaj.n = n + m + 1;
    cuplaj.G.resize(cuplaj.n + 1);
    for(i = 1; i <= k; i++){
        fin >> x >> y;
        int _w;
        fin >> _w;
        cuplaj.add_edge(x, n + y, 1, _w);
        cuplaj.add_edge(n + y, x, 0, -_w);
        cuplaj.poz[x][y] = i;
    }
    for(i = 1; i <= n; i++){
        cuplaj.add_edge(0, i, 1, 0);
        cuplaj.add_edge(i, 0, 0, 0);
    }
    for(i = n + 1; i < cuplaj.n; i++){
        cuplaj.add_edge(i, cuplaj.n, 1, 0);
        cuplaj.add_edge(cuplaj.n, i, 0, 0);
    }
    cuplaj.bellman_ford();
    pair <int, int> rez = cuplaj.edmonds_karp();
    fout << rez.first << " " << rez.second << "\n";
    for(i = 1; i <= n; i++){
        for(int j = 1; j <= m; j++){
            if(cuplaj.poz[i][j] && !cuplaj.c[i][j + n]) fout << cuplaj.poz[i][j] << " ";
        }
    }
    return 0;
}