Cod sursa(job #2878207)

Utilizator NanuGrancea Alexandru Nanu Data 26 martie 2022 10:03:20
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.9 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
 
using namespace std;
 
ifstream fin("cmcm.in");
ofstream fout("cmcm.out");
 
#define DIM 605
#define INF (1LL << 30)
 
int n, m, e;
bool sel[DIM + 1];
int Index[DIM + 1][DIM + 1];              //indicele muchiei;
int d[DIM + 1], fr[DIM + 1], t[DIM + 1];  //pentru Bellman_Ford;
int C[DIM + 1][DIM + 1], F[DIM + 1][DIM + 1]; //Cost si Flux (dinic);
vector <int > G[DIM + 1];
 
static inline bool Bellman_Ford(int S, int D) {
    for(int i = S; i <= D; i++) {
        d[i] = INF;
        fr[i] = 0;
        t[i] = 0;
    }
    d[S] = 0;
 
    queue<int> Q;
    Q.push(S);
    sel[S] = 1;
    while(!Q.empty()) {
        int nod = Q.front();
        sel[nod] = 0;
        Q.pop();
 
         fr[nod]++;         //Sa nu am ciclu, conditie optionala pt aceasta problema;
         if(fr[nod] == D)
             return 0;
 
        for(auto e : G[nod])
            if(d[e] > d[nod] + C[nod][e] && F[nod][e] > 0) {
                d[e] = d[nod] + C[nod][e];
                t[e] = nod;
                if(!sel[e]) {
                    sel[e] = 1;
                    Q.push(e);
                }
            }
    }
    return (d[D] != INF); //daca am ajuns la destinatie;
}
 
int main()
{
  fin.tie(0);
  fout.tie(0);
    fin >> n >> m >> e;
    for(int i = 1; i <= e; i++) {
        int x, y, c;
 
        fin >> x >> y >> c;
        y += n;           //nodul corespondent din a doua multime;

        Index[x][y] = i;  //indicele muchiei;
        Index[y][x] = i;

        G[x].push_back(y);
        G[y].push_back(x);
 
        C[x][y] = c;  //costul;
        C[y][x] = -c;

        F[x][y] = 1;  //fluxul e 1 ca pot merge o singura data pe o muchie;
    }
 
    int S = 0;  ///sursa
    int D = n + m + 1;  ///destinatia;
    for(int i = 1; i <= n; i++) { //Muchii de la sursa la toate nodurile din prima grupare;
        G[S].push_back(i);
        G[i].push_back(S);
        F[S][i] = 1;
    }
 
    for(int i = n + 1; i <= n + m; i++) { //muchii de la toate nodurile din a 2 a grupare la destinatie;
        G[i].push_back(D);
        G[D].push_back(i);
        F[i][D] = 1;
    }
 
    int maxflow = 0, mincost = 0;
    while(Bellman_Ford(S, D)) {
        int nod = D;
        int minim = INF;
        while(nod != S) {
            if(F[t[nod]][nod] > 0)
              minim = min(minim, F[t[nod]][nod]);
            nod = t[nod];
        }

        nod = D;
        while(nod != S) {
            F[t[nod]][nod] -= minim;
            F[nod][t[nod]] += minim;
            nod = t[nod];
        }
        maxflow += minim;
        mincost += minim * d[D];
    }
 
    fout << maxflow << " " << mincost << '\n';
    for(int i = 1; i <= n; i++)
      for(int j = 1; j <= m; j++) 
        if(!F[i][j + n] && Index[i][j + n])
          fout << Index[i][j + n] << " "; 

    return 0;
}