Cod sursa(job #3276028)

Utilizator Barbu_MateiBarbu Matei Barbu_Matei Data 12 februarie 2025 15:12:39
Problema Ubuntzei Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.7 kb
#include <bits/stdc++.h>
using namespace std;

int n, m, k;
vector<pair<int, int>> v[2001], g[2001];
int dp[2001][(1 << 15) + 1];
char c[2001];

struct path {
    int node, ub;
};

class comp {
public:
    bool operator()(path a, path b) {
        return dp[a.node][a.ub] > dp[b.node][b.ub];
    }
};

void dijkstra2() {
    memset(dp, 0x3f, sizeof(dp));
    priority_queue<path, vector<path>, comp> q;
    q.push({1, 0});
    dp[1][0] = 0;
    while (!q.empty()) {
        int node = q.top().node;
        int ub = q.top().ub;
        if (ub == (1 << k) - 1 && node == n) {
            return;
        }
        //cout << node << " " << q.top().cost << " " << ub << " " << "\n";
        q.pop();
        for (int i = 0; i < g[node].size(); ++i) {
            if (c[g[node][i].first] && ((ub & (1 << (c[g[node][i].first] - 1))) == 0)) {
                int new_ub = ub ^ (1 << (c[g[node][i].first] - 1));
                if (dp[node][ub] + g[node][i].second < dp[g[node][i].first][new_ub]) {
                    dp[g[node][i].first][new_ub] = dp[node][ub] + g[node][i].second;
                    q.push({g[node][i].first, new_ub});
                }
            } else {
                if (dp[node][ub] + g[node][i].second < dp[g[node][i].first][ub]) {
                    dp[g[node][i].first][ub] = dp[node][ub] + g[node][i].second;
                    q.push({g[node][i].first, ub});
                }
            }
        }
    }
}

void dijkstra1(int start) {
    memset(dp, 0x3f, sizeof(dp));
    priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> q;
    q.push({0, start});
    dp[start][0] = 0;
    while (!q.empty()) {
        int node = q.top().second;
        if (node != start && (c[node] || node == 1 || node == n)) {
            g[start].push_back({node, dp[node][0]});
        }
        q.pop();
        for (int i = 0; i < v[node].size(); ++i) {
            if (dp[node][0] + v[node][i].second < dp[v[node][i].first][0]) {
                dp[v[node][i].first][0] = dp[node][0] + v[node][i].second;
                q.push({dp[v[node][i].first][0], v[node][i].first});
            }
        }
    }
}

int main() {
    ifstream cin("ubuntzei.in");
    ofstream cout("ubuntzei.out");
    cin >> n >> m >> k;
    for (int i = 1; i <= k; ++i) {
        int city;
        cin >> city;
        c[city] = i;
    }
    for (int i = 1; i <= m; ++i) {
        int x, y, z;
        cin >> x >> y >> z;
        v[x].push_back({y, z});
        v[y].push_back({x, z});
    }
    for (int i = 1; i <= n; ++i) {
        if (c[i] || i == 1 || i == n) {
            dijkstra1(i);
        }
    }
    dijkstra2();
    cout << dp[n][(1 << k) - 1];
}