Cod sursa(job #1592789)

Utilizator lflorin29Florin Laiu lflorin29 Data 7 februarie 2016 22:40:54
Problema Ubuntzei Scor 75
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.48 kb
#include <bits/stdc++.h>

using namespace std;

#define X first
#define Y second
#define eb emplace_back
const int N = 1 << 11, INF = numeric_limits<int>::max() / 2;

int n, m, k;
int dist[N][N];
vector<pair<int, int>>G[N];
vector<int>a;

void add(const int &src, const int &dest, const int &weit) {
    G[src].eb(dest, weit);
    G[dest].eb(src, weit);
}

void citire() {
    ifstream fin("ubuntzei.in");
    fin >> n >> m >> k;
    a.resize(k + 2); a[0] = 1; a[k + 1] = n;
    for(int i = 1; i <= k; ++i)
        fin >> a[i];
    while(m--) {
         int src, dest, weit;
         fin >> src >> dest >> weit;
         add(src, dest, weit);
    }
}

template<class T>
void relax(int vertex, int act, vector<bool>&visited, T& que){
    for(auto pairs : G[act]) {
        int other = pairs.first, weight = pairs.second;
        if(weight + dist[vertex][act] >= dist[vertex][other])
            continue;
        dist[vertex][other] = weight + dist[vertex][act];
        if(visited[other]) continue;
        visited[other] = true;
        que.push(other);
    }
}

void calc(int vertex) {
    memset(dist[vertex], 0x3f, sizeof(dist[vertex]));
    vector<bool>visited(n + 1);
    auto cmp = [&] (const int &va, const int &vb) {
        return dist[vertex][va] > dist[vertex][vb];
    };
    priority_queue<int, vector<int>, decltype(cmp)>que(cmp);
    que.push(vertex);
    dist[vertex][vertex] = 0;

    while(!que.empty()) {
         int act = que.top();
         que.pop();
         visited[act] = 0;
         relax(vertex, act, visited, que);
    }
}

// Dist(i, j) = distanta de la nodul i la nodul j minima

void solve() {
    for(const auto &itr : a)
        calc(itr);

    const int lim = (1<<((int)a.size()+1))+1;
    vector<vector<int>>dp((int)a.size(), vector<int>(lim, INF));
    for(int i = 0; i < (int)a.size(); ++i)
       dp[i][(1 << i) | (1 << 0)] = dist[1][a[i]];

    for(int conf = 1; conf < lim ; ++conf)
        for(int i = 0; i < (int)a.size(); ++i)
            if(conf & (1 << i))
                for(int j = 0; j < (int)a.size(); ++j) {
                    if(i == j) continue;
                    if(conf & (1 << j)) continue;
                    dp[j][conf | (1 << j)] = min(dp[j][conf | (1 << j)], dp[i][conf] + dist[a[i]][a[j]]);
                }
    int msk = 0;
    for(int i=0;i<a.size();++i)msk|=1<<i;
    ofstream("ubuntzei.out") << dp[a.size() - 1][msk];
}

int main() {
    citire();
    solve();
    return 0;
}