Cod sursa(job #2566839)

Utilizator lucianul31Moisii Lucian lucianul31 Data 3 martie 2020 13:16:09
Problema Ubuntzei Scor 50
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.21 kb
#include <iostream>
#include <bits/stdc++.h>

using namespace std;

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

#define mp make_pair
#define pb push_back
const int NMAX = 2005, Infinity = 1<<29;
typedef pair < int, int > PAIR;
int n, m, K, Dist[20][20], D[NMAX], Friends[20], MIN = 1<<30;
vector < PAIR > Edge[NMAX];
priority_queue < PAIR > Q;
bitset < NMAX > Seen;
bitset < 20 > Used;

void Read()
{
    int x, y, c;
    in >> n >> m >> K;
    for(int i = 1; i <= K; i++)
        in >> Friends[i];
    for(int i = 1; i <= m; i++)
        in >> x >> y >> c, Edge[x].pb(mp(y, c)), Edge[y].pb(mp(x, c));
}

void Dijkstra(int x)
{
    for(int i = 1; i <= n; i++)
        Seen[i] = 0, D[i] = Infinity;
    D[x] = 0;
    Q.push(mp(0, x));
    while(!Q.empty())
    {
        x = Q.top().second;
        Q.pop();
        if(!Seen[x])
        {
            for(PAIR it : Edge[x])
                if(it.second + D[x] < D[it.first])
                    D[it.first] = it.second + D[x], Q.push(mp(-D[it.first], it.first));
            Seen[x] = 1;
        }
    }
}

void BKT(int k, int S, int Last)
{
    if(k == K+1 && Dist[Last+1][K+1] + S < MIN)
        MIN = Dist[Last + 1][K+1] + S;
    else
    {
        for(int i = 1; i <= K; i++)
            if(!Used[i])
            {
                Used[i] = 1;
                int s = S + Dist[i+1][Last];
                if(s < MIN)
                    BKT(k+1, s, i);
                Used[i] = 0;
            }
    }
}

int main()
{
    Read();
    for(int i = 1; i <= K; i++)
    {
        Dijkstra(Friends[i]);
        Dist[1][i] = D[1];
        Dist[i+1][K+1] = D[n];
        for(int j = 1; j <= K; j++)
            Dist[i+1][j] = D[Friends[j]];
        Dist[i+1][i] = Infinity;
    }
    Dijkstra(n);
    Dist[1][K+1] = D[1];
    if(K == 0)
    {
        out << Dist[1][1];
        return 0;
    }
    else
    {
        for(int i = 1; i <= K; i++)
            Used[i] = 1, BKT(2, Dist[1][i], i), Used[i] = 0;
        out << MIN;
    }
//    for(int i = 1; i<=K+1; i++)
//    {
//        for(int j = 1; j<=K+1; j++)
//            out<< Dist[i][j] << setw(5);
//        out<<'\n';
//    }
    return 0;
}