Cod sursa(job #2696135)

Utilizator Silviu.Stancioiu@gmail.comSilviu Stancioiu [email protected] Data 15 ianuarie 2021 13:46:06
Problema Cuplaj maxim de cost minim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.24 kb
#include <fstream>
#include <vector>
#include <queue>

using namespace std;

constexpr auto max_n = 605;
constexpr auto max_e = 50005;
constexpr auto inf = 1000000000;

ifstream fin("cmcm.in");
ofstream fout("cmcm.out");
int n, m, e;
int source_node;
int destionation_node;

vector<int> graph[max_n];
int c[max_n][max_n];
int cost[max_n][max_n];
int t1[max_e];
int t2[max_e];
bool used[max_n];
int parent[max_n];
int dist[max_n];
int flows[max_n][max_n];
queue<int> nodes_queue;

int bellman_ford()
{
    for (int i = 0; i <= destionation_node; i++)
    {
        used[i] = false;
        parent[i] = 0;
        dist[i] = inf;
    }

    nodes_queue.push(source_node);
    dist[source_node] = 0;

    while (!nodes_queue.empty())
    {
        auto crt_node = nodes_queue.front();
        nodes_queue.pop();
        used[crt_node] = false;

        if (crt_node == destionation_node)
            continue;

        for (auto& other_node : graph[crt_node])
        {
            int next_dist = dist[crt_node] + cost[crt_node][other_node];
            if (flows[crt_node][other_node] >= c[crt_node][other_node] || next_dist >= dist[other_node])
                continue;

            dist[other_node] = next_dist;

            if (!used[other_node])
            {
                nodes_queue.push(other_node);
                used[other_node] = 1;
            }

            parent[other_node] = crt_node;
        }
    }

    return dist[destionation_node] != inf;
}

void solve()
{
    int crt_node;
    int res ;
    int result = 0;
    int max_cost = 0;
    while (bellman_ford())
    {
        crt_node = destionation_node;
        res = inf;
        while (parent[crt_node] != crt_node)
        {
            res = min(res, c[parent[crt_node]][crt_node] - flows[parent[crt_node]][crt_node]);
            crt_node = parent[crt_node];
        }

        crt_node = destionation_node;
        result += dist[destionation_node] * res;
        while (parent[crt_node] != crt_node)
        {
            flows[parent[crt_node]][crt_node] += res;
            flows[crt_node][parent[crt_node]] -= res;
            crt_node = parent[crt_node];
        }

        max_cost++;
    }

    fout << max_cost << " " << result << "\n";

    for (int i = 1; i <= e; i++)
        if (flows[t1[i]][t2[i] + n] > 0)
            fout << i << " ";
}

int main()
{
    fin >> n >> m >> e;

    source_node = 0;
    destionation_node = n + m + 2;

    for (auto i = 1; i <= n; i++)
    {
        graph[source_node].push_back(i);
        c[source_node][i] = 1;
        cost[source_node][i] = 0;
    }

    for (auto i = 1; i <= m; i++)
    {
        graph[n + i].push_back(destionation_node);
        c[n + i][destionation_node] = 1;
        cost[n + i][destionation_node] = 0;
    }

    for (auto i = 1; i <= e; i++)
    {
        int cst;
        int node1;
        int node2;
        fin >> t1[i] >> t2[i] >> cst;
        
        node1 = t1[i];
        node2 = t2[i] + n;

        graph[node1].push_back(node2);
        graph[node2].push_back(node1);

        c[node1][node2] = 1;
        cost[node1][node2] = cst;
        cost[node2][node1] = -cst;
    }

    solve();

    return 0;
}