Cod sursa(job #3257529)

Utilizator catalinmarincatalinmarin catalinmarin Data 18 noiembrie 2024 10:24:05
Problema Ubuntzei Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.52 kb
#include <fstream>
#include <queue>
#include <vector>
using namespace std;

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

const int max_N = 2005;

struct vecin{
    int dest;
    int cost;
};

struct stare_dijkstra{
    int curr_node;
    int curr_cost;
    bool operator < (const stare_dijkstra &other) const {
        return curr_cost > other.curr_cost;
    }
};

int n, m;
int k;

int rez_dijk[17][max_N];
int dp[int(1 << 17) + 5][17];


vector<vecin> v[max_N];
vector<int> prieteni;

void dijkstra(int nod, int id){

    priority_queue<stare_dijkstra> pq;
    pq.push({nod, 0});

    while (!pq.empty()){

        stare_dijkstra frn = pq.top();
        pq.pop();

        if (rez_dijk[id][frn.curr_node] < frn.curr_cost)
            continue;

        for (vecin vec: v[frn.curr_node]){

            if (rez_dijk[id][vec.dest] > frn.curr_cost + vec.cost){
                rez_dijk[id][vec.dest] = frn.curr_cost + vec.cost;
                pq.push({vec.dest, frn.curr_cost + vec.cost});

            }

        }

    }

}

int main(){

    fin >> n >> m;
    fin >> k;

    prieteni.resize(k + 1);

    for (int i = 1; i <= k; i++){
        fin >> prieteni[i];
    }

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

        int a, b, c;
        fin >> a >> b >> c;
        v[a].push_back({b, c});
        v[b].push_back({a, c});

    }

    for (int i = 0; i <= k; i++){
        for (int j = 1; j <= n; j++)
            rez_dijk[i][j] = 1e9;
    }
    prieteni[0] = 1;
    for (int i = 0; i <= k; i++){

        rez_dijk[i][prieteni[i]] = 0;
        dijkstra(prieteni[i], i);

    }

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

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

        dp[(1 << i)][i] = rez_dijk[0][prieteni[i + 1]];

    }

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

        for (int last = 0; last < k; last++){

            int nod_last = (1 << last);

            if ((config & nod_last) != 0){

                for (int vec = 0; vec < k; vec++){

                    int nod_vec = (1 << vec);

                    if ((config & nod_vec) == 0)
                        dp[config | nod_vec][vec] = min(dp[config | nod_vec][vec],
                                                        dp[config][nod_last] + rez_dijk[nod_last][prieteni[vec + 1]]);

                }

            }

        }

    }

    int rez_min = 2e9;

    for (int i = 1; i <= k; i++){
        rez_min = min(rez_min, dp[(1 << k) - 1][i - 1] + rez_dijk[i][n]);
    }

    fout << rez_min;

    return 0;
}