Cod sursa(job #1906830)

Utilizator tamionvTamio Vesa Nakajima tamionv Data 6 martie 2017 16:35:54
Problema Ubuntzei Scor 25
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.34 kb
#include <bits/stdc++.h>
using namespace std;

using ll = long long;
constexpr int maxn = 2010, maxk = 20;

ifstream f("ubuntzei.in");
ofstream g("ubuntzei.out");

int n;
vector<pair<int, int>> big_vec[maxn] = {};

int dist[maxn] = {}, vec[maxk][maxk] = {};

deque<int> special_nodes;

void dijkstra(const int s){
    static priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;
    memset(dist, 0x3f, sizeof(dist));

    dist[s] = 0;
    pq.emplace(dist[s], s);

    while(!pq.empty()){
        const int cur = pq.top().second, dist_cur = pq.top().first;
        pq.pop();
        if(dist[cur] != dist_cur) continue;

        for(const auto next : big_vec[cur]){
            if(dist[next.second] > next.first + dist_cur){
                dist[next.second] = next.first + dist_cur;
                pq.emplace(dist[next.second], next.second); } } } }

ll hamiltonian_path(){
    // de la sz-2 la sz-1 in graful complet definit de matricea de adiacenta vec
    const int sz = special_nodes.size();
    static ll dist[15][1<<15] = {};
    memset(dist, 0x3f, sizeof(dist));

    for(int i = 0; i < sz-2; ++i) dist[i][1<<i] = vec[sz-2][i];
    for(int i = 2; (i>>(sz-2)) == 0; ++i){
        if(__builtin_popcount(i) < 2) continue;
        for(int s1 = i; s1; s1 ^= s1&-s1){
            for(int s2 = i; s2; s2 ^= s2&-s2){
                const int cur = __builtin_ctz(s1&-s1), prev = __builtin_ctz(s2&-s2);
                if(cur == prev) continue;
                dist[cur][i] = min(dist[cur][i], dist[prev][i ^ (1<<cur)] + vec[prev][cur]); } } }
    ll rez = dist[0][(1<<(sz-2))-1] + vec[0][sz-1];
    for(int i = 1; i < sz-2; ++i) rez = min(rez, dist[i][(1<<sz)-1] + vec[i][sz-1]);
    return rez; }

int main(){
    int m, k;
    f >> n >> m >> k;
    special_nodes.resize(k);
    for(auto& x : special_nodes) f >> x;
    special_nodes.push_back(1);
    special_nodes.push_back(n);

    for(int i = 0, x, y, d; i < m; ++i){
        f >> x >> y >> d;
        big_vec[x].emplace_back(d, y);
        big_vec[y].emplace_back(d, x); }
    if(k == 0){
        dijkstra(1);
        g << dist[n] << ' ';
        return 0; }

    for(int i = 0; i < special_nodes.size(); ++i){
        dijkstra(special_nodes[i]);
        for(int j = 0; j < special_nodes.size(); ++j){
            vec[i][j] = dist[special_nodes[j]]; } }

    g << hamiltonian_path() << endl;
    return 0; }