Cod sursa(job #2122145)

Utilizator LucaSeriSeritan Luca LucaSeri Data 4 februarie 2018 18:05:47
Problema Ubuntzei Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.18 kb
#include <bits/stdc++.h>

using namespace std;

const int MAXN = 2010;
const int MAXMASK = (1<<16);

int dp[16][MAXMASK];
int dist[MAXN][MAXN];

vector< pair<int, int> > gr[MAXN];
vector< int > masks[15];

class cmp{
    public: const bool operator()(const pair<int, int>& a, const pair<int, int> & b) const {
        return a.second > b.second;
    };
};


void dijkstra(int source){
    memset(dist[source], 0x3f, sizeof dist[source]);
    priority_queue< pair<int, int>, vector< pair<int, int> >, cmp > H;

    H.push({source, 0});
    dist[source][source] = 0;
    while(H.size()){
        int node = H.top().first;
        int cost = H.top().second;
        H.pop();
        if(cost != dist[source][node]) continue;

        for(auto& x : gr[node]){
            if(cost + x.second < dist[source][x.first]){
                dist[source][x.first] = cost + x.second;
                H.push({x.first, dist[source][x.second]});
            }
        }
    }
}

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

    int n, m;

    f >> n >> m;

    int k;

    f >> k;

    vector<int> cities(k);

    for(int i = 0; i < k; ++i) f >> cities[i];

    while(m--){
        int a, b, c;
        f >> a >> b >> c;
        gr[a].push_back({b, c});
        gr[b].push_back({a, c});
    }

    int MASKLIM = 1<<k;
    for(int i = 0; i < MASKLIM; ++i){
        masks[__builtin_popcount(i)].push_back(i);
    }

    memset(dp, 0x3f, sizeof dp);

    dijkstra(1);

    for(int i = 0; i < k; ++i){
        dijkstra(cities[i]);
        dp[i][(1<<i)] = dist[1][cities[i]];
    }

    for(int len = 1; len <= k; ++ len){
        for(int &mask : masks[len]){
            for(int bit = 0; bit < k; ++ bit){
                if((1<<bit)&mask) continue;
                for(int cur = 0; cur < k; ++ cur)
                    if((1<<cur)&mask) dp[bit][mask ^ (1<<bit)] = min(dp[bit][mask^(1<<bit)], dp[cur][mask] + dist[cities[cur]][cities[bit]]);
            }
        }
    }

    int ans = 0x3f3f3f3f;
    for(int i = 0; i < k; ++i){
        ans = min(ans, dp[i][(1<<k)-1] + dist[cities[i]][n]);
    }

    g << ans;
    return 0;
}