Submission #1278401

#TimeUsernameProblemLanguageResultExecution timeMemory
1278401linhhnt11072010Cities (BOI16_cities)C++20
100 / 100
2025 ms44668 KiB
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

const ll INF = 1e18;

ll n, m, k;
ll a[10];
vector<pair<ll,ll>> vt[100009];
ll kq[1<<10][100009]; // k <= 10

int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    cin >> n >> k >> m;
    for(int i = 1; i <= k; i++) cin >> a[i];

    for(int i = 1; i <= m; i++){
        ll u, v, c;
        cin >> u >> v >> c;
        vt[u].push_back({v, c});
        vt[v].push_back({u, c});
    }

    // init DP
    for(int mask = 0; mask < (1<<k); mask++)
        for(int i = 1; i <= n; i++)
            kq[mask][i] = INF;

    // khởi tạo 1-bit mask: từ đỉnh đặc biệt đến chính nó
    for(int i = 0; i < k; i++)
        kq[1<<i][a[i+1]] = 0;

    // Floyd-Warshall kiểu all-pairs trên subset 1-bit
    // hoặc dùng Dijkstra cho từng subset (nhiều cách)

    // DP trên tất cả subset
    for(int mask = 1; mask < (1<<k); mask++){
        // merge subset con
        for(int sub = mask; sub; sub = (sub-1)&mask){
            ll other = mask ^ sub;
            if(other == 0) continue; // chỉ merge khi other != 0
            for(int u = 1; u <= n; u++){
                if(kq[sub][u] == INF) continue;
                for(auto [v, cost] : vt[u]){
                    if(kq[other][v] == INF) continue;
                    kq[mask][v] = min(kq[mask][v], kq[sub][u] + cost + kq[other][v]);
                }
            }
        }
        // optional: Dijkstra/Floyd để "lan tỏa" DP trong mask
        // nếu muốn dùng edge đi qua nhiều đỉnh trung gian
        priority_queue<pair<ll,int>, vector<pair<ll,int>>, greater<pair<ll,int>>> pq;
        for(int i = 1; i <= n; i++)
            if(kq[mask][i] != INF)
                pq.push({kq[mask][i], i});

        while(!pq.empty()){
            auto [d, u] = pq.top(); pq.pop();
            if(d != kq[mask][u]) continue;
            for(auto [v,c] : vt[u]){
                if(kq[mask][v] > d + c){
                    kq[mask][v] = d + c;
                    pq.push({kq[mask][v], v});
                }
            }
        }
    }

    ll res = INF;
    for(int i = 1; i <= n; i++)
        res = min(res, kq[(1<<k)-1][i]);

    cout << res << "\n";
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...