Cod sursa(job #2531114)

Utilizator cyg_vladioanBirsan Vlad cyg_vladioan Data 25 ianuarie 2020 18:15:02
Problema Gather Scor 80
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.33 kb
#include <cstdio>
#include <algorithm>
#include <set>
#include <vector>
using namespace std;
const int NMAX = 750;
const int KMAX = 16;
const int INF = (1 << 30) - 1;
struct muchii
{
    int nod , cost , d;
};
muchii temp;
vector <muchii> G[NMAX + 5] , T[KMAX + 5];
int c[KMAX + 5][NMAX + 5][KMAX + 5] , d[(1 << KMAX) + 5][KMAX + 5] , v[KMAX + 5] , p[(1 << KMAX) + 5];
int main()
{
    freopen("gather.in" , "r" , stdin);
    freopen("gather.out" , "w" , stdout);
    int n , m , k , i , j , l , x , y , z , t , dmin , cost , nrd , lim , new_d , aux , new_bitmask;
    scanf("%d%d%d" , &k , &n , &m);
    for(i = 1 ; i <= k ; i ++)
        scanf("%d" , &v[i]);
    sort(v + 1 , v + k + 1);
    v[0] = 1;
    for(i = 1 ; i <= m ; i ++)
    {
        scanf("%d%d%d%d" , &x , &y , &z , &t);
        if(t > k)
            t = k;
        temp.nod = y;
        temp.cost = z;
        temp.d = t;
        G[x].push_back(temp);
        temp.nod = x;
        G[y].push_back(temp);
    }
    for(i = 0 ; i <= k ; i ++)
        for(j = 1 ; j <= n ; j ++)
            for(l = 0 ; l <= k ; l ++)
                c[i][j][l] = INF;
    set <pair <int , pair <int , int> > > s;
    set <pair <int , pair <int , int> > >::iterator it;
    for(i = 0 ; i <= k ; i ++)
    {
        c[i][v[i]][k] = 0;
        s.insert(make_pair(0 , make_pair(v[i] , k)));
        while(!s.empty())
        {
            it = s.begin();
            x = (*it).second.first;
            cost = (*it).first;
            nrd = (*it).second.second;
            s.erase(s.begin());
            if(cost > c[i][x][nrd])
                continue;
            for(j = 0 ; j < G[x].size() ; j ++)
            {
                y = G[x][j].nod;
                new_d = min(nrd , G[x][j].d);
                cost = G[x][j].cost;
                aux = c[i][x][nrd] + cost;
                if(c[i][y][new_d] > aux)
                {
                    c[i][y][new_d] = aux;
                    s.insert(make_pair(c[i][y][new_d] , make_pair(y , new_d)));
                }
            }
        }
    }
    for(i = 0 ; i <= k ; i ++)
        for(j = 0 ; j <= k ; j ++)
            if(i != j)
            {
                temp.nod = j;
                for(l = 0 ; l <= k ; l ++)
                    if(c[i][v[j]][l] != INF)
                    {
                        temp.cost = c[i][v[j]][l];
                        temp.d = l;
                        T[i].push_back(temp);
                    }
            }
    k ++;
    lim = (1 << k) - 1;
    for(i = 0 ; i <= lim ; i ++)
        for(j = i ; j ; j = (j >> 1))
            p[i] = p[i] + (j & 1);
    for(i = 0 ; i < k ; i ++)
        for(j = 0 ; j <= lim ; j ++)
            d[j][i] = INF;
    d[1][0] = 0;
    for(i = 1 ; i <= lim ; i ++)
        for(j = 0 ; j < k ; j ++)
            if((i & (1 << j)) != 0)
                for(l = 0 ; l < T[j].size() ; l ++)
                    if((i & (1 << T[j][l].nod)) == 0 && T[j][l].d >= p[i] - 1)
                    {
                        new_bitmask = (i | (1 << T[j][l].nod));
                        d[new_bitmask][T[j][l].nod] = min(d[new_bitmask][T[j][l].nod] , d[i][j] + p[i] * T[j][l].cost);
                    }
    dmin = INF;
    for(i = 0 ; i < k ; i ++)
        dmin = min(dmin , d[lim][i]);
    printf("%d\n" , dmin);
    return 0;
}