Cod sursa(job #1906783)

Utilizator tamionvTamio Vesa Nakajima tamionv Data 6 martie 2017 16:21:21
Problema Ubuntzei Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.11 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 0 la 1 in graful complet definit de matricea de adiacenta vec
    static ll dist[maxk][1<<maxk] = {};
    memset(dist, 0x3f, sizeof(dist));

    const int sz = special_nodes.size();
    dist[0][1] = 0;
    for(int i = 2; (i>>sz) == 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 || cur == 0 || prev == 1) continue;
                dist[cur][i] = min(dist[cur][i], dist[prev][i ^ (1<<cur)] + vec[prev][cur]); } } }
    return dist[1][(1<<sz)-1]; }

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

    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); }

    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; }