Cod sursa(job #2764087)

Utilizator DragosC1Dragos DragosC1 Data 19 iulie 2021 13:40:43
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.74 kb
#include <fstream>
#include <vector>
#include <queue>
#include <iostream>
using namespace std;
 
int n, m, E;
vector<pair<int, int>> a[705];
int C[705][705], F[705][705], edge[705][705];
int sol;
int t[705];
 
const int Inf = 1e9;
 
void read() {
    int i, x, y, cost;
    ifstream f("cmcm.in");
    f >> n >> m >> E;
    for (i = 1; i <= E; i++) {
        f >> x >> y >> cost; x++, y += 1 + n;
        a[x].emplace_back(y, cost);
        a[y].emplace_back(x, -cost);
        C[x][y] = 1;
        edge[x][y] = i;
    }
    f.close();
}
 
void buildGraph() {
    int sink = n + m + 2, i;
    for (i = 2; i <= n + 1; i++) {
        a[1].emplace_back(i, 0);
        a[i].emplace_back(1, 0);
        C[1][i] = 1;
    }
    for (i = n + 2; i <= n + m + 1; i++) {
        a[i].emplace_back(sink, 0);
        a[sink].emplace_back(i, 0);
        C[i][sink] = 1;
    }
}
 
queue<int> Q;
bool viz[705];
int d[705];
 
int bellmanford() {
    int i, x;
    for (i = 1; i <= n + m + 2; i++) {
        d[i] = Inf;
        viz[i] = 0;
        t[i] = -1;
    }
 
    viz[1] = 1;
    d[1] = 0;
    Q.push(1);
    while (!Q.empty()) {
        x = Q.front();
        Q.pop();
        viz[x] = 0;
        for (i = 0; i < a[x].size(); i++) 
            if (F[x][a[x][i].first] != C[x][a[x][i].first] && d[x] + a[x][i].second < d[a[x][i].first]) {
                d[a[x][i].first] = d[x] + a[x][i].second;
                t[a[x][i].first] = x;
                if (!viz[a[x][i].first]) {
                    viz[a[x][i].first] = 1;
                    Q.push(a[x][i].first);
                }
            }
    }
 
    // ford-fulkerson
    if (d[n + m + 2] < Inf) {
        int flux = Inf;
        int nod = n + m + 2;
        while (nod != 1) {
            flux = min(flux, C[t[nod]][nod] - F[t[nod]][nod]);
            nod = t[nod];
        }
        nod = n + m + 2;
        while (nod != 1) {
            F[t[nod]][nod] += flux;
            F[nod][t[nod]] -= flux;
            nod = t[nod];
        }
        return flux * d[n + m + 2];
    }
 
    return 0;
}
 
void solve() {
    int i, improve;
 
    buildGraph();
 
    improve = 1;
    while (improve) {
        improve = bellmanford();
        sol += improve;
    }
}
 
void output() {
    ofstream g("cmcm.out");
    int i, j, nr = 0;
    for (i = 2; i <= n + 1; i++)
        for (j = n + 2; j <= n + m + 1; j++)
            if (C[i][j] && F[i][j])
                nr++;
    g << nr << ' ' << sol << '\n';
    for (i = 2; i <= n + 1; i++)
        for (j = n + 2; j <= n + m + 1; j++)
            if (C[i][j] && F[i][j])
                g << edge[i][j] << ' ';
    g.close();
}
 
int main() {
    read();
    solve();
    output();
    return 0;
}