Cod sursa(job #1423067)

Utilizator retrogradLucian Bicsi retrograd Data 21 aprilie 2015 09:14:59
Problema Barman Scor 10
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.67 kb
#include<fstream>
#include<vector>
#include<unordered_map>
#include<cstring>
#include<queue>
#include<algorithm>
#include<map>

using namespace std;
typedef int var;

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

typedef pair<var, var> pii;
#define mp make_pair

#define MAXN 1000

var A[MAXN];
vector<var> B;
var n;
unordered_map<var, var> Norm;
map<var, var> Map;
vector<var> Buck[MAXN], Buck2[MAXN];

#define L(a) (2*a)
#define R(a) (2*a+1)
#define S 0
#define D 1
#define cost(a,b) (20+min(b-a,a+n-b))


#define MAXNO 1500
var K[MAXNO][MAXNO], F[MAXNO][MAXNO], C[MAXNO][MAXNO];
vector<var> G[MAXNO];

void addEdge(var s, var d, var cost) {
    G[s].push_back(d);
    G[d].push_back(s);

    K[s][d] = cost;
    K[d][s] = -cost;
    C[s][d] = 1;
    C[d][s] = 0;
    F[s][d] = 0;
    F[d][s] = 0;
}

void buildGraph(var val) {

    //var n = Buck[val].size();

    for(auto l : Buck[val]) {
        G[L(l)].clear();
    }
    for(auto r : Buck2[val]) {
        G[R(r)].clear();
    }
    G[S].clear();
    G[D].clear();

    for(auto l : Buck[val]) {
        for(auto r : Buck2[val]) {
            if(l == r) {
                addEdge(L(l), R(r), 0);
            } else {
                addEdge(L(l), R(r), cost(min(l, r),max(l, r)));
            }
        }
    }

    for(auto l : Buck[val]) {
        addEdge(S, L(l), 0);
    }

    for(auto r : Buck2[val]) {
        addEdge(R(r), D, 0);
    }
}

var Parent[MAXNO], Dist[MAXNO];
bool Inq[MAXNO];
queue<var> Q;

bool bellman() {

    memset(Dist, 0xf, sizeof(Dist));
    memset(Parent, 0, sizeof(Parent));

    Dist[S] = 0;
    Q.push(S);

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

        for(auto vec : G[node]) {
            if(Dist[vec] > Dist[node] + K[node][vec] && F[node][vec] < C[node][vec]) {
                Dist[vec] = Dist[node] + K[node][vec];
                Parent[vec] = node;

                if(!Inq[vec]) {
                    Q.push(vec);
                    Inq[vec] = 1;
                }
            }
        }
    }

    return Parent[D] != 0;
}

var bipart() {
    var total = 0;
    while(bellman()) {
        for(var node = D; node != S; node = Parent[node]) {
            F[Parent[node]][node] ++;
            F[node][Parent[node]] --;
            total += K[Parent[node]][node];
        }
    }
    return total;
}

var best = 0xffff;

void solve() {

    var cost = 0;
    for(var i=0; i<Norm.size(); i++) {
        buildGraph(i);
        cost += bipart();
    }

    best = min(best, cost);
}

void afisvList(string msg, vector<var> V[MAXN], var size) {
    fout<<msg<<'\n';
    for(var i=0; i<size; i++) {
        if(V[i].empty()) continue;

        fout<<i<<": ";
        for(auto t : V[i])
            fout<<t<<" ";
        fout<<endl;
    }
    fout<<endl;
}

int main() {

    fin>>n;

    for(var i=1; i<=n; i++) {
        fin>>A[i];
        Map[A[i]] = 1;
    }

    var c=0;
    for(auto p : Map) {
        Norm[p.first] = c++;
    }


    for(var i=1; i<=n; i++) {
        A[i] = Norm[A[i]];
        Buck[A[i]].push_back(i);
    }

    var poz = 0;
    for(var i=0; i<Norm.size(); i++) {
        for(auto &j : Buck[i]) {
            Buck2[i].push_back(++poz);
        }
    }

    //afisvList("Buck:", Buck, Norm.size());

    for(var d=1; d<=n; d++) {
        for(var i=0; i<Norm.size(); i++) {
            for(auto &j : Buck2[i]) {
                j = (j%n)+1;
            }
        }

        //afisvList("Buck2:", Buck2, Norm.size());

        solve();
    }


    fout<<best;

    return 0;
}