Cod sursa(job #3202145)

Utilizator RobertAcAcatrinei Robert-Marian RobertAc Data 10 februarie 2024 19:47:24
Problema Cc Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.38 kb
#include <bits/stdc++.h>
#ifdef LOCAL
#define in cin
#define out cout
#endif

using namespace std;

#ifndef LOCAL
ifstream in("cc.in");
ofstream out("cc.out");
#endif

const int nmax = 207;
const int inf = 2e9;

int s, d;
int cntE = 0;
int pi[nmax];
int dist[nmax];
vector<int> adj[nmax];
int enter[nmax];

struct edge
{
    int fr, to, c, w;
    edge(int fr = 0, int to = 0, int c = 0, int w = 0) : fr(fr), to(to), c(c), w(w) {}
    int rw()
    {
        return pi[fr] - pi[to] + w;
    }
} edges[nmax * nmax * 2];

void resetDist()
{
    for (int i = s; i <= d; i++)
    {
        dist[i] = inf;
    }
}

void toPi()
{
    for (int i = s; i <= d; i++)
    {
        pi[i] += dist[i];
    }
}

bool dijkstra()
{
    struct dijelem
    {
        int a, b;
        dijelem(int a, int b) : a(a), b(b) {}
        bool operator<(const dijelem &other) const
        {
            return b > other.b;
        }
    };
    priority_queue<dijelem> pq;
    pq.push({s, 0});
    resetDist();
    dist[s] = 0;
    while (!pq.empty())
    {
        auto node = pq.top();
        pq.pop();
        for (auto i : adj[node.a])
        {
            if (edges[i].c == 0)
                continue;
            int to = edges[i].to;
            if (dist[to] > dist[node.a] + edges[i].rw())
            {
                dist[to] = dist[node.a] + edges[i].rw();
                enter[to] = i;
                pq.push({to, dist[to]});
            }
        }
    }
    if (dist[d] == inf)
        return 0;
    toPi();
    return 1;
}

void addE(int fr, int to, int c, int w)
{
    edges[cntE] = {fr, to, c, w};
    edges[cntE + 1] = {to, fr, 0, -w};
    adj[fr].push_back(cntE);
    adj[to].push_back(cntE + 1);
    cntE += 2;
}

void dfs(int node, int &cst)
{
    if (node == s)
        return;
    int ind = enter[node];
    cst += edges[ind].w;
    edges[ind].c -= 1;
    edges[ind ^ 1].c += 1;
    dfs(edges[ind].fr, cst);
}

int main()
{
    int n;
    in >> n;
    s = 0;
    d = n * 2 + 1;
    for (int i = 1; i <= n; i++)
    {
        addE(s, i, 1, 0);
    }
    for (int i = n + 1; i <= 2 * n; i++)
    {
        addE(i, d, 1, 0);
    }
    for (int i = 1; i <= n; i++)
    {
        for (int j = n + 1; j <= 2 * n; j++)
        {
            int w;
            cin >> w;
            addE(i, j, 1, w);
        }
    }
    int res = 0;
    while (dijkstra())
    {
        int cst = 0;
        dfs(d, cst);
        res += cst;
    }
    cout << res;
}