Cod sursa(job #2025166)

Utilizator cristina_borzaCristina Borza cristina_borza Data 21 septembrie 2017 22:59:34
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.37 kb
#include <fstream>
#include <queue>

using namespace std;

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

const int Inf = 1e9 + 5;
const int Dim = 1e5 + 5;

int c[50], d[ Dim ], dp[50000][20], dist[50][50];
int n, m, k, x, y, cost, ans;

vector <pair <int, int> > G[ Dim ];

class comp {
public:
    bool operator()(int& t1, int& t2){
       return d[t1] > d[t2];
    }
};priority_queue <int, std :: vector<int>, comp> coada;

void dijkstra (int node) {
    for (int i = 0; i <= n + 1; ++i) {
        d[i] = Inf;
    }

    coada.push (node);
    d[node] = 0;

    while (!coada.empty()){
        int node = coada.top();
        coada.pop();

        int nr = G[node].size();
        for(int i = 0; i < nr ; ++i){
            int aux = G[node][i].second + d[node];
            if (aux < d[G[node][i].first]){
                d[G[node][i].first] = aux ;
                coada.push (G[node][i].first);
            }
        }
    }
}

int main() {
    f >> n >> m >> k;
    for (int i = 1; i <= k; ++i) {
        f >> c[i];
    }

    for (int i = 1; i <= m; ++i) {
        f >> x >> y >> cost;
        G[x].push_back ({y, cost});
        G[y].push_back ({x, cost});
    }

    if (k == 0) {
        dijkstra (1);
        g << d[n];
        return 0;
    }

    for (int i = 1; i <= k; ++i) {
        dijkstra (c[i]);
        for (int j = 1; j <= k; ++j) {
            dist[i][j] = dist[j][i] = d[c[j]];
        }

        dist[0][i] = dist[i][0] = d[1];
        dist[k + 1][i] = dist[i][k + 1] = d[n];
    }

    for (int mask = 1; mask < (1 << k); ++mask) {
        for (int i = 0; i < k; ++i) {
            dp[mask][i] = Inf;
            if (((1 << i) & mask) != 0) {
                bool ok = 0;
                for (int j = 0; j < k; ++j) {
                    if (i == j)
                        continue;

                    if (((1 << j) & mask) != 0) {
                        ok = 1;
                        dp[mask][i] = min (dp[mask][i], dp[mask - (1 << i)][j] + dist[i + 1][j + 1]);
                    }
                }

                if (!ok) {
                    dp[mask][i] = dist[i + 1][0];
                }
            }
        }
    }

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

    g << ans;
    return 0;
}