Cod sursa(job #3193514)

Utilizator TL_2022T123 L456 TL_2022 Data 14 ianuarie 2024 19:08:51
Problema Cc Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.54 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <limits.h>

const int INF = INT_MAX;

std::vector<std::vector<int>> adj_list, cost, capacity;

void shortest_paths(int n, int v0, std::vector<int>& d, std::vector<int>& p)
{
    d.assign(n, INF);
    d[v0] = 0;
    std::vector<bool> inq(n, false);
    std::queue<int> q;
    q.push(v0);
    p.assign(n, -1);

    while(!q.empty())
    {
        int u = q.front();
        q.pop();
        inq[u] = false;
        for(int v: adj_list[u])
        {
            if(capacity[u][v] > 0 && d[v] > d[u] + cost[u][v])
            {
                d[v] = d[u] + cost[u][v];
                p[v] = u;
                if(!inq[v])
                {
                    inq[v] = true;
                    q.push(v);
                }
            }
        }
    }
}

std::pair<int, int> min_cost_flow(int n, int s, int t, int k = INF)
{
    int flow = 0;
    int cost = 0;
    std::vector<int> d, p;
    while(flow < k)
    {
        shortest_paths(n, s, d, p);
        if(d[t] == INF)
            break;

        int f = k - flow;
        int node = t;
        while(node != s)
        {
            f = std::min(f, capacity[p[node]][node]);
            node = p[node];
        }

        flow += f;
        cost += f * d[t];
        node = t;
        while(node != s)
        {
            capacity[p[node]][node] -= f;
            capacity[node][p[node]] += f;
            node = p[node];
        }
    }

    return {flow, cost};
}

int main()
{
    std::ifstream f("cc.in");
    std::ofstream g("cc.out");

    int n_=0;
    f >> n_;
    int n = 2*n_ + 2;
    int s = 0, t = 2*n_ +1;
    adj_list.assign(n, std::vector<int>());
    cost.assign(n, std::vector<int>(n, 0));
    capacity.assign(n, std::vector<int>(n, 0));

    int dist = 0;
    for(int i=1;i<=n_;i++)
        for(int j=1;j<=n_;j++)
        {
            f >> dist;
            adj_list[i].push_back(n_+j);
            adj_list[n_+j].push_back(i);
            cost[i][n_+j] = dist;
            cost[n_+j][i] = -dist;
            capacity[i][n_+j] = 1;
        }
    for(int i=1;i<=n_;i++)
    {
        adj_list[s].push_back(i);
        adj_list[i].push_back(s);
        capacity[s][i] = 1;
    }
    for(int i=1;i<=n_;i++)
    {
        adj_list[n_+i].push_back(t);
        adj_list[t].push_back(n_+i);
        capacity[n_+i][t] = 1;
    }

    auto rez = min_cost_flow(n, s, t);
    g << rez.second;

    f.close();
    g.close();
    return 0;
}