Cod sursa(job #2093595)

Utilizator circeanubogdanCirceanu Bogdan circeanubogdan Data 24 decembrie 2017 02:11:16
Problema Gather Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.61 kb
#include <fstream>
#include <vector>
#include <set>
#define DIM 752
#define DIM_K 17
#define INF 1e9
#define ynod first
#define cost second.first
#define pmax second.second

using namespace std;

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

int n, m, k, priz[DIM], x, y, c, p, d[DIM_K][DIM_K][DIM], dp[(1<<DIM_K) + 10][DIM_K];

vector<pair<int, pair<int, int> > > graf[DIM];

set<pair<int, int> > s;

bool test(int i, int j){
    return !(i & (1<<j));
}

int nr_bit(int i){
    int nr = 0;
    for(; i; i -= (i & -i))
        ++ nr;
    return nr;
}

int main()
{
    f>>k>>n>>m;
    for(int i = 0; i < k; ++ i)
        f>>priz[i];
    for(int i = 1; i <= m; ++ i){
        f>>x>>y>>c>>p;
        graf[x].push_back(make_pair(y, make_pair(c, p)));
        graf[y].push_back(make_pair(x, make_pair(c, p)));
    }
    for(int i = 0; i < k; ++ i)
        for(int j = 0; j <= k; ++ j)
            for(int k = 1; k <= n; ++ k)
                d[i][j][k] = INF;
    for(int i = 0; i < k; ++ i){
        s.clear();
        for(int j = 0; j <= k; ++ j){
            s.insert(make_pair(0, priz[i]));
            d[i][j][priz[i]] = 0;
            while(!s.empty()){
                pair<int, int> nod = *s.begin();
                s.erase(s.begin());
                for(int cnt = 0; cnt < graf[nod.second].size(); ++ cnt){
                    pair<int, pair<int, int> > nodc = graf[nod.second][cnt];
                    if(d[i][j][nodc.ynod] > d[i][j][nod.second] + nodc.cost && nodc.pmax >= j){
                        if(d[i][j][nodc.ynod] != INF && !s.empty()){
                            s.erase(make_pair(d[i][j][nodc.ynod], nodc.ynod));
                        }
                        d[i][j][nodc.ynod] = d[i][j][nod.second] + nodc.cost;
                        s.insert(make_pair(d[i][j][nodc.ynod], nodc.ynod));
                    }
                }
            }
        }
    }

    int kdim = (1<<k) - 1;
    for(int i = 1; i <= kdim; ++ i)
        for(int j = 0; j < k; ++ j)
            dp[i][j] = INF;

    for(int i = 0; i < k; ++ i)
        dp[(1<<i)][i] = d[i][0][1];

    for(int i = 1; i <= kdim; ++ i)
        for(int j = 0; j < k; ++ j)
            if(!test(i, j))
                for(int l = 0; l < k; ++ l)
                    if(test(i, l)){
                        int nr_det = nr_bit(i);
                        dp[i + (1<<l)][l] = min(dp[i + (1<<l)][l], dp[i][j] + (nr_det + 1) * d[j][nr_det][priz[l]]);
                    }
    int minim = INF;
    for(int i = 0; i < k; ++ i)
        minim = min(minim, dp[kdim][i]);
    g<<minim;

    return 0;
}