Cod sursa(job #2555910)

Utilizator XXMihaiXX969Gherghinescu Mihai Andrei XXMihaiXX969 Data 24 februarie 2020 15:25:44
Problema Ubuntzei Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.17 kb
#include <bits/stdc++.h>

using namespace std;

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

const int DIM = 2e3 + 7;
const int DIM2 = (1 << 17);
const int INF = 1e9;

int n, m, k;

int loc[17];

vector <pair <int, int> > l[DIM];

int d[DIM][DIM];
int dp[DIM2][20];

bool ex[DIM];

priority_queue < pair <int, int> > q;

void dijkstra(int x, int d[DIM])
{
    for(int i = 1; i <= n; i++)
        d[i] = INF;

    ex[x] = true;

    d[x] = 0;

    q.push(make_pair(0,x));


    while(!q.empty())
    {
        int nod = q.top().second;
        q.pop();
        ex[nod] = false;

        for(int i = 0; i < l[nod].size(); i++)
        {
            int vec = l[nod][i].first;
            int cost = l[nod][i].second;

            if(d[vec] > d[nod] + cost)
            {
                d[vec] = d[nod] + cost;

                if(ex[vec] == false)
                {
                    ex[vec] = true;
                    q.push(make_pair(-cost, vec));
                }
            }
        }
    }
}

int main()
{
    in >> n >> m;

    in >> k;

    for(int i = 1; i <= k; i++)
        in >> loc[i];

    for(int i = 1; i <= m; i++)
    {
        int x, y , z;

        in >> x >> y >> z;

        l[x].push_back(make_pair(y, z));
        l[y].push_back(make_pair(x, z));

    }

    dijkstra(1, d[1]);

    for(int i = 1; i <= k; i++)
        dijkstra(loc[i],d[loc[i]]);


    if(k == 0)
    {
            out << d[1][n];
            return 0;
    }

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


    for(int i = 1; i <= k; i++)
        dp[(1 << (i - 1))][i] = d[1][loc[i]];

    for(int i = 1; i < (1 << k); i++)
        for(int j = 1; j <= k; j++)
            if(i & (1 << (j - 1)))
                for(int t = 1; t <= k; t++)
                    if(t != j && (i & (1 << (t - 1))))
                        dp[i][j] = min(dp[i][j], dp[i ^ (1 << (j - 1))][t] + d[loc[t]][loc[j]]);


    int rez = INF;

    for(int i = 1; i <= k; i++)
        rez = min(rez, dp[(1 << k) - 1][i] + d[loc[i]][n]);

    out << rez;

    return 0;
}