Cod sursa(job #2875014)

Utilizator florinrafiliuRafiliu Florin florinrafiliu Data 20 martie 2022 17:30:47
Problema Cuplaj maxim de cost minim Scor 60
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.98 kb

#include <bits/stdc++.h>

using namespace std;

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

const int maxN = 660;
const int INF = 1e9;

int parent[maxN], dist[maxN], old[maxN], distNew[maxN];
int a[maxN][maxN], cost[maxN][maxN], ind[maxN][maxN], fr[maxN];

vector <int> g[maxN];
vector <int> ans;

int dijkstra (int source, int sink, int n) {
    for(int i = 0; i <= n; ++i) {
        parent[i] = -1;
        dist[i] = INF;
    }

    priority_queue <pair<int,int>> q;

    q.push({0, source});

    dist[source] = 0;
    parent[source] = -2;

    while(q.size() > 0) {
        pair <int,int> x = q.top();
        q.pop();

        int distNode = -x.first;
        int node = x.second;

        if(dist[node] < distNode)
            continue;

        for(int to : g[node])
            if(a[node][to] > 0) {
                int newDistance = distNode + cost[node][to] + (old[node] - old[to]);
                if(dist[to] > newDistance) {
                    dist[to] = newDistance;
                    distNew[to] = distNew[node] + cost[node][to];

                    parent[to] = node;
                    q.push({-newDistance, to});
                }
            }
    }

    for(int i = 0; i <= n; ++i)
        old[i] = distNew[i];

    if(parent[sink] == -1)
        return 0;
    return parent[sink];
}

int maxFlowMinCost (int source, int sink, int n) {
    int flow = 0;
    int flowCost = 0;

    while(dijkstra(source, sink, n)) {
        int newFlow = INF;

        int to = sink;
        while(to != source) {
            int node = parent[to];

            newFlow = min(newFlow, a[node][to]);

            to = node;
        }

        to = sink;
        while(to != source) {
            int node = parent[to];

            a[node][to] -= newFlow;
            a[to][node] += newFlow;

            fr[node] ++;
            fr[to] ++;

            to = node;
        }

        flow += newFlow;
        flowCost += newFlow * old[sink];
    }

    return flowCost;
}

int main() {

    int n, m, e;
    fin >> n >> m >> e;

    int source = 0, sink = n + m + 1;
    for(int i = 1; i <= e; ++i) {
        int u, v, cst;
        fin >> u >> v >> cst;

        v += n;

        a[u][v] = 1;
        cost[u][v] += cst;
        cost[v][u] -= cst;

        ind[u][v] = i;

        g[u].push_back(v);
        g[v].push_back(u);
    }

    for(int i = 1; i <= n; ++i) {
        a[source][i] = 1;
        g[source].push_back(i);
        g[i].push_back(source);
    }

    for(int i = n+1; i <= n+m; ++i) {
        a[i][sink] = 1;
        g[sink].push_back(i);
        g[i].push_back(sink);
    }

    int flowC = maxFlowMinCost(source, sink, n+m+1);

    for(int i = 1; i <= n; ++i)
        for(int j : g[i])
            if(a[j][i] != 0)
                ans.push_back(ind[i][j]);

    fout << ans.size() << " " << flowC << "\n";

    for(int i : ans)
        fout << i << " ";

    return 0;
}