Cod sursa(job #3241292)

Utilizator Sasha_12454Eric Paturan Sasha_12454 Data 28 august 2024 16:11:08
Problema Ubuntzei Scor 80
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.49 kb
#include <bits/stdc++.h>

const std :: string FILENAME = "ubuntzei";

std :: ifstream in (FILENAME + ".in");

std :: ofstream out (FILENAME + ".out");

const int NMAX = 2e3;

const int DIM = 15;

const int INF = 1e9;

int n;

int m;

int k;

int x;

int y;

int d;

int ans = INF;

int c[DIM];

int dp[1 << DIM][DIM];

int dist[DIM][NMAX];

std :: vector <std :: pair <int, int>> v[NMAX];

std :: priority_queue <std :: pair <int, int>> pq;

std :: bitset <NMAX> visited;

void dijkstra(int start)
{
    while(!pq.empty())
    {
        int nod = pq.top().second;

        pq.pop();

        if(visited[nod] == false)
        {
            visited[nod] = true;

            for(auto i : v[nod])
            {
                if(dist[start][nod] + i.second < dist[start][i.first])
                {
                    dist[start][i.first] = dist[start][nod] + i.second;

                    pq.push(std :: make_pair(-dist[start][i.first], i.first));
                }
            }
        }
    }
}

int main()
{

    in >> n >> m;

    in >> k;

    for(int i = 0; i < k; i ++)
    {
        in >> x;

        c[i] = x - 1;
    }

    for(int i = 1; i <= m; i ++)
    {
        in >> x >> y >> d;

        x --;

        y --;

        v[x].push_back(std :: make_pair(y, d));

        v[y].push_back(std :: make_pair(x, d));
    }

    for(int i = 0; i < k; i ++)
    {
        for(int j = 0; j < n; j ++)
        {
            dist[i][j] = INF;
        }
    }

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

    for(int i = 0; i < k; i ++)
    {
        dist[i][c[i]] = 0;

        visited &= 0;

        pq.push(std :: make_pair(0, c[i]));

        dijkstra(i);

        dp[1 << i][i] = dist[i][0];
    }

    for(int mask = 1; mask < (1 << k); mask ++)
    {
        for(int i = 0; i < k; i ++)
        {
            if(mask & (1 << i))
            {
                for(int j = 0; j < k; j ++)
                {
                    if((mask ^ (1 << i)) & (1 << j))
                    {
                        dp[mask][i] = std :: min(dp[mask][i], dp[mask ^ (1 << i)][j] + dist[i][c[j]]);
                    }
                }
            }
        }
    }

    for(int i = 0; i < k; i ++)
    {
        ans = std :: min(ans, dp[(1 << k) - 1][i] + dist[i][n - 1]);
    }

    out << ans;

    return 0;
}