Cod sursa(job #1635057)

Utilizator BrandonChris Luntraru Brandon Data 6 martie 2016 14:54:35
Problema Ubuntzei Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.76 kb
#include <fstream>
#include <vector>
#include <queue>
#include <cstring>

#define INF 0x3f3f3f3f
using namespace std;

ifstream cin("ubuntzei.in");
ofstream cout("ubuntzei.out");

class PriorityQ {
public:
    int node, dist;
};

class Graph {
public:
    int node, road;
};

class cmp {
public:
    inline bool operator ()(PriorityQ a, PriorityQ b) {
        return a.dist > b.dist;
    }
};

vector <Graph> G[2005];
vector <int> friends;
priority_queue <PriorityQ, vector <PriorityQ>, cmp> prioQ;

int k, n, m, dist[2005][2005], max_sum, ham[16][(1 << 15) + 5];

void dijkstra(int st) {
    prioQ.push({st, 0});
    dist[st][st] = 0;

    while(!prioQ.empty()) {
        PriorityQ frn = prioQ.top();
        prioQ.pop();

        for(auto nxt: G[frn.node]) {
            int new_dist = frn.dist + nxt.road;

            if(new_dist > dist[st][nxt.node]) {
                continue;
            }

            dist[st][nxt.node] = new_dist;
            prioQ.push({nxt.node, new_dist});
        }
    }
}

int hamilton() {
    memset(ham, INF, sizeof ham);

    for(int i = 0; i < k; ++i) {
        ham[i][1 << i] = dist[1][friends[i]];
    }

    for(int bitmask = 1; bitmask < (1 << k); ++bitmask) {
        for(int frn = 0; frn < k; ++frn) {
            if(ham[frn][bitmask] == INF) {
                continue;
            }

            for(int nxt = 0; nxt < k; ++nxt) {
                //int nxt_node = nxt;
                int nxt_cost = dist[friends[frn]][friends[nxt]];

                if(!(bitmask & (1 << nxt))) {
                    ham[nxt][bitmask ^ (1 << nxt)] = min(ham[nxt][bitmask ^ (1 << nxt)], ham[frn][bitmask] + nxt_cost);
                }
            }
        }
    }

    int ans = INF;

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

    return ans;
}

int main() {
    cin >> n >> m >> k;

    if(!k) {
        cout << dist[1][n] << '\n';
        return 0;
    }

    for(int i = 1; i <= k; ++i) {
        int x;
        cin >> x;
        friends.push_back(x);
    }

    for(int i = 1; i <= m; ++i) {
        int a, b, d;
        cin >> a >> b >> d;
        G[a].push_back({b, d});
        G[b].push_back({a, d});
    }

    memset(dist, INF, sizeof dist);
    dijkstra(1);

    for(auto it: friends) {
        dijkstra(it);
    }

    /*for(int i = 1; i <= n; ++i) {
        for(int j = 1; j <= n; ++j) {
            cout << dist[i][j] << ' ';
        }

        cout << '\n';
    }*/

    cout << hamilton() << '\n';

    /*for(int i = 0; i < k; ++i) {
        for(int j = 0; j <= (1 << k); ++j) {
            cout << ham[i][j] << ' ';
        }

        cout << '\n';
    }*/

    return 0;
}