Cod sursa(job #2125695)

Utilizator andra_moldovanAndra Moldovan andra_moldovan Data 8 februarie 2018 17:43:19
Problema Ubuntzei Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.26 kb
#include <fstream>
#include <queue>
#include <vector>
#include <cstring>

#define MAXN 2005
#define inf 0x3f3f3f3f

using namespace std;

ifstream fin("ubuntzei.in");
ofstream fout("ubuntzei.out");

int N, M, K, ubuntzel[17];
int cost[17][MAXN], dp[(1 << 17) - 1][22];

struct str{
    int node, cc;

    bool operator < (const str& other) const {
        return cc > other.cc;
    }
};

vector <str> graph[MAXN];
priority_queue <str> Q;

void Read() {
    int x, y, z;

    fin >> N >> M;
    fin >> K;

    for (int i = 1; i <= K; i++)
        fin >> ubuntzel[i];
    for (int i = 1; i <= M; i++) {
        fin >> x >> y >> z;

        graph[x].push_back({y, z});
        graph[y].push_back({x, z});
    }
}

inline void Dijkstra(int u) {
    int z, c;

    Q.push({ubuntzel[u], 0});
    cost[u][ubuntzel[u]] = 0;

    while (!Q.empty()) {
        z = Q.top().node;
        c = Q.top().cc;

        Q.pop();

        if (c != cost[u][z])
            continue;

        for (auto x : graph[z]) {
            if (cost[u][x.node] > c + x.cc) {
                cost[u][x.node] = c + x.cc;

                Q.push({x.node, c + x.cc});
            }
        }
    }
}

void Solve() {
    int sol = inf, nn, mask, val;

    memset(cost, inf, sizeof(cost));

    for (int i = 1; i <= K; i++) {
        Dijkstra(i);
    }

    ///Ciclu hamiltonian de cost minim
    ///dp[mask][bit] = costul minim pt a ajunge in config mask, ultimul ubuntzei fiind bit
    nn = (1 << K) - 1;
    memset(dp, inf, sizeof(dp));
    for (int i = 0; i < K; i++)
        dp[1 << i][i] = 0;

    for (int i = 1; i <= nn; i++) {
        for (int j = 0; j < K; j++) {
            mask = i & (1 << j);

            if (mask) {
                val = mask - (1 << j); ///config fara j
                for (int q = 0; q < K; q++) {
                    if (val & (1 << q)) {
                        dp[i][j] = min(dp[i][j], dp[val][q] + cost[j][q + 1]);
                    }
                }
            }
        }
    }

    for (int i = 1; i <= K; i++) {
        sol = min(sol, dp[nn][i - 1] + cost[i][N] + cost[i][1]);
    }

    fout << sol;
}

int main () {
    Read();
    Solve();

    fin.close(); fout.close(); return 0;
}