Cod sursa(job #2212873)

Utilizator caesar2001Stoica Alexandru caesar2001 Data 15 iunie 2018 01:12:03
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.28 kb
#include <bits/stdc++.h>

using namespace std;
ifstream in("ubuntzei.in");
ofstream out("ubuntzei.out");

const int NMAX = 2005;
const int INF = 2000000000;
vector<int> g[NMAX];
vector<int> cost[NMAX];
int dist[NMAX][NMAX], dp[(1 << 15) + 2][20], special[20], n, m, k;

struct Data {
    int node, co;
    bool operator<(Data other) const {
        return co > other.co;
    }
};
priority_queue<Data> hp;
bool visited[NMAX];

void dijkstra(int x) {
    memset(visited, 0, sizeof visited);
    hp.push({x, 0});
    while(hp.size()) {
        Data i = hp.top();
        hp.pop();
        if(!visited[i.node]) {
            visited[i.node] = 1;
            dist[x][i.node] = i.co;
            dist[i.node][x] = i.co;
            for(int u = 0; u < g[i.node].size(); u ++)
                if(!visited[g[i.node][u]])
                    hp.push({g[i.node][u], i.co + cost[i.node][u]});
        }
    }
}

int main() {
    in >> n >> m >> k;
    for(int i = 1; i <= k; i ++)
        in >> special[i];
    for(int i = 1; i <= m; i ++) {
        int x, y, c;
        in >> x >> y >> c;
        g[x].push_back(y);
        cost[x].push_back(c);
        g[y].push_back(x);
        cost[y].push_back(c);
    }
    memset(dist, -1, sizeof dist);
    for(int i = 1; i <= k; i ++)
        dijkstra(special[i]);
    if(k == 0) {
        dijkstra(1);
        out << dist[1][n];
        return 0;
    }
    for(int i = 0; i <= (1 << 15); i ++)
        for(int j = 0; j <= 15; j ++)
            dp[i][j] = INF;
    for(int i = 0; i < k; i ++) {
        int pas = 1 << i;
        dp[pas][i+1] = dist[special[i+1]][1];
    }
    for(int i = 1; i < (1 << k); i ++) {
        for(int j = 0; j < k; j ++) {
            int aux = i & (1 << j);
            if(aux != 0 && i - (1 << j) > 0) {
                    aux = i - (1 << j);
                    for(int l = 0; l < k; l ++)
                        if(l != j && dist[special[l + 1]][special[j + 1]] != -1 && dp[aux][l+1] != INF)
                            dp[i][j+1] = min(dp[i][j+1], dp[aux][l+1] + dist[special[l + 1]][special[j + 1]]);
            }
        }
    }
    int sol = INF;
    for(int i = 1; i <= k; i ++)
        sol = min(dp[(1 << k) - 1][i] + dist[special[i]][n], sol);
    out << sol;
    return 0;
}