Cod sursa(job #2223273)

Utilizator LucaSeriSeritan Luca LucaSeri Data 19 iulie 2018 16:31:26
Problema Cc Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.92 kb
#include<bits/stdc++.h>

using namespace std;

const int MAXN = 205;

int source = 0;
int target = MAXN-1;

int n;

int currentFlow[MAXN][MAXN];
int capacity[MAXN][MAXN];
int cost[MAXN][MAXN];
int potential[MAXN];
int distances[MAXN];
int father[MAXN];

vector< int > gr[MAXN];

class cmp {
public:
    const bool operator()(const pair< int, int > &a, const pair< int, int > &b) const {
        return a.second > b.second;
    }
};

bool moreFlow() {
    priority_queue< pair< int, int >, vector< pair< int, int > >, cmp > H;
    H.push(make_pair(source, 0));

    memset(distances, 0x3f, sizeof distances);
    memset(father, 0, sizeof father);
    distances[source] = 0;

    while(H.size()) {
        int node, currentCost;
        tie(node, currentCost) = H.top();
        H.pop();

        if(distances[node] != currentCost) continue;

        for(auto x : gr[node]) {
            if(currentFlow[node][x] < capacity[node][x]) {
                if(distances[x] > currentCost + cost[node][x] + potential[node] - potential[x]) {
                    distances[x] = currentCost + cost[node][x] + potential[node] - potential[x];
                    father[x] = node;
                    H.push(make_pair(x, distances[x]));
                }
            }
        }
    }

    memcpy(potential, distances, sizeof potential);

    return (father[target] != 0);
}

int main() {
    ios::sync_with_stdio(false);

    ifstream f("cc.in");
    ofstream g("cc.out");

    f >> n;

    for(int i = 1; i <= n; ++i) {
        for(int j = n+1; j <= 2*n; ++j) {
            f >> cost[i][j];
            gr[i].emplace_back(j);
            gr[j].emplace_back(i);
            cost[j][i] = -cost[i][j];
            capacity[i][j] = 1;
        }
    }

    gr[source].resize(n);

    for(int i = 0; i < n; ++i) {
        gr[source][i] = i+1;
        capacity[source][i+1] = 1;
        gr[i+1].emplace_back(source);
    }

    gr[target].resize(n);

    for(int i = 0; i < n; ++i) {
        gr[target][i] = n+i+1;
        capacity[n+i+1][target] = 1;
        gr[n+i+1].emplace_back(target);
    }

    while(moreFlow()) {
        int node = target;
        int minFlow = static_cast<int>(1e9);

        while(node) {
            minFlow = min(minFlow, capacity[father[node]][node] - currentFlow[father[node]][node]);
            node = father[node];
        }

        node = target;

        while(node) {
            currentFlow[father[node]][node] += minFlow;
            currentFlow[node][father[node]] -= minFlow;
            node = father[node];
        }
    }

    int ans = 0;
    int cnt = 0;
    for(int i = 1; i <= n; ++i) {
        for(int j = n+1; j <= 2*n; ++j) {
            if(currentFlow[i][j]) {
                ++cnt;
                ans += cost[i][j];
                break;
            }
        }
    }

    assert(cnt == n);
    g << ans;
    return 0;
}