Cod sursa(job #3359514)

Utilizator rares89_Dumitriu Rares rares89_ Data 29 iunie 2026 13:15:48
Problema Traseu Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.26 kb
#include <bits/stdc++.h>

using namespace std;

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

struct Edge {
    int to, rev, cap;
    long long cost;
};

const long long INF = 4e18;

int n, m, source, sink;
long long ans;
long long dist[65][65];
int in[65], out[65];

vector<vector<Edge>> G;
vector<long long> d;
vector<int> parentNode, parentEdge;

void addEdge(int x, int y, int cap, long long cost) {
    Edge a = {y, (int)G[y].size(), cap, cost};
    Edge b = {x, (int)G[x].size(), 0, -cost};

    G[x].push_back(a);
    G[y].push_back(b);
}

bool bellman() {
    queue<int> Q;
    vector<int> inQueue(sink + 1, 0);

    d.assign(sink + 1, INF);
    parentNode.assign(sink + 1, 0);
    parentEdge.assign(sink + 1, 0);

    d[source] = 0;
    Q.push(source);
    inQueue[source] = 1;

    while (!Q.empty()) {
        int node = Q.front();
        Q.pop();
        inQueue[node] = 0;

        for (int i = 0; i < (int)G[node].size(); ++i) {
            Edge edge = G[node][i];

            if (edge.cap > 0 && d[edge.to] > d[node] + edge.cost) {
                d[edge.to] = d[node] + edge.cost;
                parentNode[edge.to] = node;
                parentEdge[edge.to] = i;

                if (!inQueue[edge.to]) {
                    Q.push(edge.to);
                    inQueue[edge.to] = 1;
                }
            }
        }
    }

    return d[sink] != INF;
}

long long minCost() {
    long long cost = 0;

    while (bellman()) {
        int flow = 2e9;

        for (int node = sink; node != source; node = parentNode[node]) {
            int p = parentNode[node];
            int e = parentEdge[node];

            flow = min(flow, G[p][e].cap);
        }

        for (int node = sink; node != source; node = parentNode[node]) {
            int p = parentNode[node];
            int e = parentEdge[node];

            G[p][e].cap -= flow;
            G[node][G[p][e].rev].cap += flow;
        }

        cost += 1LL * flow * d[sink];
    }

    return cost;
}

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

    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= n; ++j)
            dist[i][j] = INF;

        dist[i][i] = 0;
    }

    for (int i = 1; i <= m; ++i) {
        int x, y, c;
        fin >> x >> y >> c;

        ans += c;
        ++out[x];
        ++in[y];

        dist[x][y] = min(dist[x][y], 1LL * c);
    }

    for (int k = 1; k <= n; ++k) {
        for (int i = 1; i <= n; ++i) {
            for (int j = 1; j <= n; ++j) {
                if (dist[i][k] != INF && dist[k][j] != INF)
                    dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]);
            }
        }
    }

    source = 0;
    sink = 2 * n + 1;

    G.resize(sink + 1);

    for (int i = 1; i <= n; ++i) {
        if (in[i] > out[i])
            addEdge(source, i, in[i] - out[i], 0);

        if (out[i] > in[i])
            addEdge(n + i, sink, out[i] - in[i], 0);
    }

    for (int i = 1; i <= n; ++i) {
        if (in[i] > out[i]) {
            for (int j = 1; j <= n; ++j) {
                if (out[j] > in[j])
                    addEdge(i, n + j, 2e9, dist[i][j]);
            }
        }
    }

    fout << ans + minCost() << "\n";

    return 0;
}