Cod sursa(job #1541606)

Utilizator japjappedulapPotra Vlad japjappedulap Data 4 decembrie 2015 14:03:11
Problema Ubuntzei Scor 15
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.9 kb
#include <cstring>
#include <fstream>
#include <vector>
#include <queue>
using namespace std;

ifstream is ("ubuntzei.in");
ofstream os ("ubuntzei.out");

const int Nmax = 2001;
const int INF = 0x3f3f3f3f;
int N, M;
int K, Nodes[17];
vector <pair<int,int> > Graph[Nmax];

int Cost[17][17];
int D[1<<17][17];

int Dist[Nmax];
bool B[Nmax];
priority_queue <pair<int,int>, vector <pair<int,int> >, greater<pair<int,int> > > Q;    // val, node

void Read();
void Dijkstra(int);
void DP();

int main()
{
    Read();
    for (int i = 0; i <= K+1; ++i)
    {
        Dijkstra(Nodes[i]);
        for (int j = 0; j <= K+1; ++j)
            Cost[i][j] = Dist[Nodes[j]];
    }
    DP();
}

void DP()
{
    memset(D, INF, sizeof(D));
    D[1][0] = 0;
    ++K;
    ++K;
    for (int mask = 2; mask < (1<<K); ++mask)
        for (int i = 0; (1<<i) <= mask; ++i)
            if (mask & (1<<i))    //checkbit 1
                for (int j = 0; (1<<j) <= mask; ++j)
                    if (mask & (1<<j) )
                        D[mask][i] = min(D[mask][i], D[mask - (1<<i)][j] + Cost[j][i]);

    os << D[(1<<K)-1][K-1];
};

void Dijkstra(int start)
{
    memset(Dist, INF, sizeof(Dist));
    memset(B, 0, sizeof(B));
    Dist[start] = 0;
    Q.push({start, 0});
    for (int x; !Q.empty(); )
    {
        x = Q.top().first;
        B[x] = 1;
        for (const auto& Y : Graph[x])
        {
            if (Dist[Y.first] > Dist[x] + Y.second)
            {
                Dist[Y.first] = Dist[x] + Y.second;
                Q.push({Y.first, Dist[Y.first]});
            }
        }
        while (!Q.empty() && B[Q.top().first] == 1)
            Q.pop();
    }
};


void Read()
{
    is >> N >> M;
    is >> K;
    for (int i = 1; i <= K; ++i)
        is >> Nodes[i];
    Nodes[0] = 1;
    Nodes[K+1] = N;
    for (int a, b, c; M; --M)
    {
        is >> a >> b >> c;
        Graph[a].push_back({b, c});
        Graph[b].push_back({a, c});
    }
};