Cod sursa(job #2963176)

Utilizator SerbanCaroleSerban Carole SerbanCarole Data 10 ianuarie 2023 11:10:08
Problema Ubuntzei Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.85 kb
#include <fstream>
#include <vector>
#include <queue>
using namespace std;

/////////////////////////////////////

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

const int KMAX = 16;

const int MAX = 2e3 + 1;

const int inf = 1e11;

int dp[KMAX][(1<<KMAX)] , dij[MAX][MAX] , c[KMAX] , n , k , m , full;

struct nod{

    int y , c;

};

vector <nod> g[MAX];

struct cmp{

    bool operator()( nod x , nod y){

        return x.c > y.c;

    }

};

priority_queue<nod,vector<nod>,cmp> pq;

/////////////////////////////////////

void dijkstranormal(){

    nod x;

    x.y = 1;
    x.c = 0;

    for(int i = 1 ; i <= n ; i++) dij[1][i] = inf;

    dij[1][1] = 0;

    pq.push(x);

    while(!pq.empty()){

        x = pq.top();

        pq.pop();

        for(auto it : g[x.y]){

            if(dij[1][it.y] > dij[1][x.y] + it.c){

                dij[1][it.y] = dij[1][x.y] + it.c;

                pq.push({it.y,dij[1][it.y]});
            }
        }
    }
}

void initdp(){

    for(int i = 1 ; i <= full ; i++){

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

    for(int i = 1 ; i <= k ; i++){

        dp[i][(1<<(i-1))] = dij[c[i]][1];
    }

}

void init( int x){

    for( int i = 1 ; i <= n ; i++) dij[x][i] = inf;

    dij[x][x] = 0;

}

void dijkstra( int x ){

    nod y , aux;

    y.c = 0;

    y.y = x;

    pq.push(y);

    while(!pq.empty()){

        aux = pq.top();

        pq.pop();

        for(auto it : g[aux.y]){

            if( dij[x][it.y] > dij[x][aux.y] + it.c){

                dij[x][it.y] = dij[x][aux.y] + it.c;

                pq.push({it.y,dij[x][it.y]});
            }
        }
    }

}

int main()
{


    cin >> n >> m;

    cin >> k;

    for(int i = 1 ; i <= k ; i++){

        cin >> c[i];
    }

    int x , y , cost;

    for(int i = 1 ; i <= m ; i++){

        cin >> x >> y >> cost;

        g[x].push_back({y,cost});
        g[y].push_back({x,cost});
    }

    if(!k){

        dijkstranormal();

        cout << dij[1][n];

        return 0;
    }

    for(int i = 1 ; i <= k ; i++){

        init(c[i]);

        dijkstra(c[i]);
    }

    full = (1<<k) - 1;

    initdp();

    for(int mask = 1 ; mask <= full ; mask++){

        for(int i = 1 ; i <= k ; i++){

            if((mask&(1<<(i-1))) && dp[i][mask] != inf){

                for(int j = 1 ; j <= k ; j++){

                    if( i != j && !(mask&(1<<(j-1))) ){

                        dp[j][(mask | (1<<(j-1)))] = min(dp[j][(mask | (1<<(j-1)))] , dp[i][mask] + dij[c[i]][c[j]]);
                    }
                }
            }
        }
    }


    int ans = inf;

    for(int i = 1 ; i <= k ; i++) ans = min(ans,dp[i][full] + dij[c[i]][n]);

    cout << ans;

    return 0;
}