Cod sursa(job #2861478)

Utilizator cezar.balutaCezar Baluta cezar.baluta Data 4 martie 2022 00:55:44
Problema Ubuntzei Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.5 kb
/*
                         __
                   _.--""  |
    .----.     _.-'   |/\| |.--.
    |    |__.-'   _________|  |_)  _______________
    |  .-""-.""""" ___,    `----'"))   __   .-""-.""""--._
    '-' ,--. `    |Cezar| .---.       |:.| ' ,--. `      _`.
     ( (    ) ) __|  7  |__\\|// _..-- \/ ( (    ) )--._".-.
      . `--' ;\__________________..--------. `--' ;--------'
       `-..-'                               `-..-'
*/
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <bitset>

using namespace std;

struct muchie{
    int y,cost;
};

const int N = 2e3 + 5;
const int M = 16;
const int INF = (1<<29);

int a[M];
vector<muchie>v[N];
int dp[(1<<(M+2))][M];
int drum[N][N];
bitset <N> inq;

struct comparare{
    bool operator()(int a, int b){
        return drum[a]>drum[b];
    }
};

void init(int n, int m){
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            drum[i][j] = INF;
        }
    }
    for(int i=0;i<(1<<m);i++)
        for(int j=0;j<m;j++){
            dp[i][j] = INF;
        }
}

int drum_hamiltonian(int n){
    dp[1][0] = 0;
    for(int mask = 1;mask<(1<<n);mask++){
        for(int i = 0;i<n;i++){
            if((mask & (1<<i)) && dp[mask][i] !=INF){
                for(int j=0;j<n;j++){
                    int new_mask = mask | (1<<j);
                    dp[new_mask][j] = min(dp[new_mask][j],dp[mask][i] + drum[a[i]][a[j]]);
                }
            }
        }
    }
  return dp[(1<<n)-1][n-1];
}

void dijkstra(int start, int n){
    priority_queue<int,vector<int>,comparare>q;
    int x;
    x = start;
    q.push(x);
    drum[start][x] = 0;
    while(!q.empty()){
        x = q.top();
        inq[x] = false;
        q.pop();
        for(auto y:v[x]){
            if(drum[start][y.y]>drum[start][x] + y.cost){
                drum[start][y.y] = drum[start][x] + y.cost;
                if(!inq[y.y]){
                    inq[y.y] = true;
                    q.push(y.y);
                }
            }
        }
    }

}

int main() {
    ifstream in("ubuntzei.in");
    ofstream out("ubuntzei.out");
    int n,m,k;
    in>>n>>m>>k;

    a[0] = 1;
    for(int i=1;i<=k;i++){
        in>>a[i];
    }
    k++;
    a[k] = n;
    int x,y,cost;
    muchie add;
    for(int i=0;i<m;i++){
        in>>x>>y>>cost;
        add.y = y;
        add.cost = cost;
        v[x].push_back(add);
        add.y = x;
        v[y].push_back(add);
    }
    init(n+1,k+1);
    for(int i=0;i<=k;i++){
        dijkstra(a[i],n);
    }
    out<<drum_hamiltonian(k+1);
    return 0;
}