Cod sursa(job #1356879)

Utilizator japjappedulapPotra Vlad japjappedulap Data 23 februarie 2015 17:15:10
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.94 kb
#include <fstream>
#include <vector>
#include <cstring>
#include <queue>
using namespace std;

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

#define PII pair<int, int>

const int INF = 0x3f3f3f3f;
int N, M, K;
int C[17][17], X[17];   //cele K+2 noduri indexate de la 0!!
int D[1<<17][17];
int Di[2001];
bool B[2001];

vector <PII> G[2001];
priority_queue<PII, vector<PII>, greater<PII> > Q;
void Read();
void Dijkstra(int x);
void Dynamic();

int main()
{
    Read();
    for (int i = 0; i < K; ++i)
    {
        Dijkstra(X[i]);
        for (int j = 0; j < K; ++j)
            if (Di[X[j]] == 0)
                C[i][j] = INF;
            else
                C[i][j] = Di[X[j]];
    }
    Dynamic();
}

void Dynamic()
{
    for (int i = 0; i < (1 << K); ++i)
        for (int j = 0; j < K; ++j)
            D[i][j] = INF;
    D[1][0] = 0;
    for (int i = 0; i < (1 << K); ++i)
        for (int j = 0; j < K; ++j)
            if (i & (1 << j))
            for (int k = 0; k < K; ++k)
                if ((i & (1 << k)) == 0 &&
                    D[i | (1 << k)][k] > D[i][j] + C[j][k])
                    D[i | (1 << k)][k] = D[i][j] + C[j][k];
    os << D[(1 << K) - 1][K-1];
};

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

#define j ax.first
#define w ax.second

void Dijkstra(int x)
{
    memset(Di, INF, sizeof(Di));
    memset(B, 0, sizeof(B));
    Di[x] = 0;
    Q.push({0, x});
    for (int i; !Q.empty();)
    {
        i = Q.top().second;
        B[i] = 1;
        for (const PII& ax : G[i])
            if (Di[j] > Di[i] + w)
            {
                Di[j] = Di[i] + w;
                Q.push({Di[j], j});
            }
        while (!Q.empty() && B[Q.top().second] == 1)
            Q.pop();
    }
};