Cod sursa(job #3245733)

Utilizator db_123Balaban David db_123 Data 30 septembrie 2024 12:10:02
Problema Ubuntzei Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.63 kb
#include <fstream>
#include <vector>
#include <algorithm>
#include <set>

using namespace std;

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

struct Info {
    int node2;
    int w;
    Info() = default;
    Info(int node2, int w) : node2(node2), w(w) {}
};

int n, m, k;
vector<int> pref;
vector<vector<Info>> graph;

void read() {
    cin >> n >> m >> k;
    k = min(15, n - 2);
    pref.resize(k);
    for (int i = 0; i < k; i++) {
        cin >> pref[i];
    }
    graph.resize(n + 1);
    for (int i = 1; i <= m; i++) {
        int a, b, c;
        cin >> a >> b >> c;
        graph[a].push_back(Info(b, c));
        graph[b].push_back(Info(a, c));
    }
}

vector<int> dijkstra2(int node) {
    struct InfoSet {
        int node;
        int w;
        InfoSet() = default;
        InfoSet(int node, int w) : node(node), w(w) {}
        bool operator<(InfoSet a2) const {
            if (w == a2.w) {
                return node < a2.node;
            }
            return w < a2.w;
        }
    };

    vector<int> dist(n + 1, 1e9);
    set<InfoSet> st;
    dist[node] = 0;
    st.insert(InfoSet(node, 0));
    
    InfoSet tp;
    while (!st.empty()) {
        tp = (*st.begin());
        st.erase(st.begin());

        for (auto it : graph[tp.node]) {
            if (dist[it.node2] > dist[tp.node] + it.w) {
                dist[it.node2] = dist[tp.node] + it.w;
                st.insert(InfoSet(it.node2, dist[it.node2]));
            }
        }
    }

    return dist;
}

int dijkstra() {
    sort(pref.begin(), pref.end(), less<int>());

    vector<vector<int>> dp(n + 1, vector<int>(1 << k, 1e9));

    vector<bool> fr_pref(n + 1);
    for (auto it : pref) {
        fr_pref[it] = 1;
    }
    
    dp[1][((pref[0] == 1) ? 1 : 0)] = 0;
    
    for (int mask = 0; mask < (1 << k); mask ++) {
        for (int i = 1; i <= n; i++) {
            if (fr_pref[i]) {

                int idx = 0;
                for (int j = 0; j < k; j++) {
                    if (pref[j] == i) {
                        idx = j;
                        break;
                    }
                }
                if ((mask & (1 << idx)) == 0) {
                    continue;
                }

                for (auto it : graph[i]) {
                    dp[i][mask] = min(dp[i][mask], dp[it.node2][mask - (1 << idx)] + it.w);
                }
            }
            else {
                for (auto it : graph[i]) {
                    dp[i][mask] = min(dp[i][mask], dp[it.node2][mask] + it.w);
                }
            }
        }
    }

    return dp[n][(1 << k) - 1];
}

void solve() {
    cout << dijkstra();
}

int main() {

    read();
    solve();
    return 0;
}