Cod sursa(job #2570739)

Utilizator niculaandreiNicula Andrei Bogdan niculaandrei Data 4 martie 2020 18:55:52
Problema Ubuntzei Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.01 kb
#include <bits/stdc++.h>
#define N_MAX 2005
#define K_MAX 18

using namespace std;

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

int N, M, K;

vector < int > fratii;

vector < pair < int, int > > G[N_MAX];

priority_queue < pair < int, int >, vector < pair < int, int > >, greater < pair < int, int > > > PQ;
int D[K_MAX][N_MAX], vis[N_MAX];

void Dijkstra(int root)
{
    int currNode = PQ.top().second;
    int currCost = PQ.top().first;
    PQ.pop();
    while (PQ.size() && vis[currNode])
    {
        currNode = PQ.top().second;
        currCost = PQ.top().first;
        PQ.pop();
    }
    vis[currNode] = 1;
    for (pair < int, int > node: G[currNode])
        if (vis[node.second] == 0 && D[root][node.second] > currCost + node.first)
        {
            D[root][node.second] = currCost + node.first;
            PQ.push(make_pair(D[root][node.second], node.second));
        }
    if (PQ.size())
        Dijkstra(root);
}

int dp[(1 << K_MAX)][K_MAX];

void Hamilton()
{
    for (int mask = 0; mask < (1 << K); mask++)
        for (int i = 0; i < K; i++)
            dp[mask][i] = INT_MAX / 2;

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

    for (pair < int, int > node: G[0])
        dp[1 | (1 << node.second)][node.second] = node.first;

    for (int mask = 0; mask < (1 << K); mask++)
        for (int i = 1; i < K; i++)
            if (mask & (1 << i))
                for (pair < int, int > node: G[i])
                    if ((mask & (1 << node.second)) == 0)
                        dp[mask | (1 << node.second)][node.second] = min(dp[mask | (1 << node.second)][node.second], dp[mask][i] + node.first);
}

int main()
{
    fin >> N >> M >> K;
    for (int i = 1; i <= K; i++)
    {
        int x;
        fin >> x;
        fratii.push_back(x);
    }
    fratii.push_back(1);
    fratii.push_back(N);
    sort(fratii.begin(), fratii.end());
    if (fratii[fratii.size() - 1] == fratii[fratii.size() - 2])
        fratii.pop_back();
    if (fratii[0] == fratii[1])
    {
        swap(fratii[0], fratii[fratii.size() - 1]);
        fratii.pop_back();
    }

    K = fratii.size();

    for (int i = 1; i <= M; i++)
    {
        int x, y, d;
        fin >> x >> y >> d;
        G[x].push_back(make_pair(d, y));
        G[y].push_back(make_pair(d, x));
    }

    for (int i = 0; i < K; i++)
        for (int j = 1; j <= N; j++)
            D[i][j] = INT_MAX / 2;

    for (int i = 0; i < K; i++)
    {
        PQ.push(make_pair(0, fratii[i]));
        D[i][fratii[i]] = 0;
        Dijkstra(i);

        for (int i = 1; i <= N; i++)
            vis[i] = 0;
    }

    for (int i = 1; i <= N; i++)
        G[i].clear();

    for (int i = 0; i < K; i++)
        for (int j = i + 1; j < K; j++)
        {
            G[i].push_back(make_pair(D[i][fratii[j]], j));
            G[j].push_back(make_pair(D[j][fratii[i]], i));
        }

    Hamilton();

    fout << dp[(1 << K) - 1][K - 1] << "\n";
    return 0;
}