Cod sursa(job #2631690)

Utilizator pregoliStana Andrei pregoli Data 30 iunie 2020 16:26:13
Problema Ubuntzei Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.25 kb
#include <bits/stdc++.h>
#define newline '\n'
using namespace std;
ifstream fin("ubuntzei.in");
ofstream fout("ubuntzei.out");
///***********************
const int NMAX = 2003, KMAX = 17, STATEMAX = 1 << KMAX, OO = 2e9;
struct edge {
    int to, cost;
    bool operator < (const edge &other) const {
        return cost > other.cost;
    }
};
int n, m, k;
int cost[KMAX][KMAX], dp[STATEMAX][KMAX], target[KMAX], dis[NMAX];
vector<edge> graph[NMAX];

void read() {
    fin >> n >> m >> k;
    for (int i = 1; i <= k; i++)
        fin >> target[i];
    target[0] = 1, target[++k] = n;
    for (int i = 0; i < m; i++) {
        int x, y, c;
        fin >> x >> y >> c;
        graph[x].push_back({y, c});
        graph[y].push_back({x, c});
    }
}

void dijkstra(int node) {
    fill(dis, dis + NMAX, OO);
    dis[node] = 0;
    priority_queue<edge> q;
    q.push({node, 0});
    while (!q.empty()) {
        node = q.top().to;
        q.pop();
        for (auto it : graph[node]) {
            if (dis[it.to] > dis[node] + it.cost) {
                dis[it.to] = dis[node] + it.cost;
                q.push({it.to, dis[it.to]});
            }
        }
    }
}

void build() {
    for (int i = 0; i <= k; i++) {
        dijkstra(target[i]);
        for (int j = 0; j <= k; j++)
            cost[i][j] = dis[target[j]];
    }
}

void computeDP() {
    int targetState = (1 << k) - 1;
    for (int state = 0; state <= targetState; state++)
        for (int i = 0; i <= k; i++)
            dp[state][i] = OO;
    dp[1][0] = 0;
    for (int i = 0; i <= k; i++)
        dp[1 << i][i] = cost[0][i];
    for (int state = 0; state <= targetState; state++)
        for (int i = 0; i <= k; i++)
            if (state & (1 << i))
                for (int j = 0; j <= k; j++)
                    if (!(state & (1 << j)) && cost[i][j]) {
                        int newState = state | (1 << j);
                        dp[newState][j] = min(dp[newState][j], dp[state][i] + cost[i][j]);
                    }
    int ans = OO;
    for (int i = 0; i < k; i++)
        ans = min(ans, dp[targetState][i] + cost[i][k]);
    fout << ans << newline;
}

int main() {
    read();
    build();
    computeDP();
    fout.close();
    return 0;
}