Cod sursa(job #2545275)

Utilizator IoanaDraganescuIoana Draganescu IoanaDraganescu Data 12 februarie 2020 22:48:57
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.39 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <cstring>

using namespace std;

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

const int Nmax = 600, inf = 0x3f3f3f3f;

vector <int> g[Nmax + 5];
queue <int> q;
int n, l, r, m, start, stop, node, ans, flow;
int c[Nmax + 5][Nmax + 5], f[Nmax + 5][Nmax + 5], cost[Nmax + 5][Nmax + 5], d[Nmax + 5], tt[Nmax + 5], edge[Nmax + 5][Nmax + 5];
bool inq[Nmax + 5];

void Read(){
    fin >> l >> r >> m;
    start = 0;
    stop = l + r + 1;
    for (int i = 1; i <= m; i++){
        int x, y, z;
        fin >> x >> y >> z;
        y += l;
        edge[x][y] = i;
        g[x].push_back(y);
        g[y].push_back(x);
        c[x][y] = 1;
        cost[x][y] = z;
        cost[y][x] = -z;
    }
    for (int i = 1; i <= l; i++){
        g[start].push_back(i);
        c[start][i] = 1;
    }
    for (int i = 1; i <= r; i++){
        g[i + l].push_back(stop);
        c[i + l][stop] = 1;
    }
    n = l + r + 1;
}

int BellmanFord(){
   memset(d, inf, sizeof d);
   memset(inq, 0, sizeof inq);
   memset(tt, 0, sizeof tt);
   q.push(start);
   d[start] = 0;
   inq[start] = 1;
   while (!q.empty()){
        node = q.front();
        q.pop();
        inq[node] = 0;
        for (auto other : g[node])
            if (d[other] > d[node] + cost[node][other] && c[node][other] - f[node][other] > 0){
                d[other] = d[node] + cost[node][other];
                tt[other] = node;
                if (!inq[other]){
                    q.push(other);
                    inq[other] = 1;
                }
            }
   }
   return d[stop] != inf;
}

void Solve(){
    while (BellmanFord()){
        int addmin = inf;
        for (int i = stop; i != start; i = tt[i])
            addmin = min(addmin, c[tt[i]][i] - f[tt[i]][i]);
        for (int i = stop; i != start; i = tt[i]){
            f[tt[i]][i] += addmin;
            f[i][tt[i]] -= addmin;
            ans += addmin * cost[tt[i]][i];
        }
    }
}

void Print(){
    for (int i = 1; i <= l; i++)
        flow += f[start][i];
    fout << flow << ' ' << ans << '\n';
    for (int i = 1; i <= l; i++)
        for (int j = 1; j <= r; j++)
            if (f[i][j + l])
                fout << edge[i][j + l] << ' ';
    fout << '\n';
}

int main(){
    Read();
    Solve();
    Print();
    return 0;
}