Cod sursa(job #1589813)

Utilizator depevladVlad Dumitru-Popescu depevlad Data 4 februarie 2016 14:27:05
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.45 kb
#include <fstream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <queue>

using namespace std;

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

const int N = 2005;
const int K = 15;
const int CFG = 1 << K;
const int INF = 0x3fffffff;

class Node {
public:
    int i;
    int d;

    bool operator <(const Node &other) const {
        return this->d > other.d;
    }
};

int n, m, k;
int dist[N];
int special[K];
int kdist[K][K];
int dp[K][CFG];
vector < pair < int, int > > adj[N];
priority_queue < Node > Q;

void dijkstra(int s) {
    int u, v, d, c;

    for(int i = 1; i <= n; i++) dist[i] = INF;
    dist[s] = 0;
    Q.push(Node{s, 0});

    while(!Q.empty()) {
        u = Q.top().i;
        d = Q.top().d;
        Q.pop();

        if(d == dist[u]) {
            for(auto i : adj[u]) {
                v = i.first;
                c = i.second;

                if(dist[v] > d + c) {
                    dist[v] = d + c;
                    Q.push(Node{v, d + c});
                }
            }
        }
    }
}

int main() {
    int i, j, t, u, v, c, nrcfg, newcfg, ans;

    in >> n >> m >> k;
    for(i = 0; i < k; i++) in >> special[i];

    for(i = 1; i <= m; i++) {
        in >> u >> v >> c;
        adj[u].push_back(make_pair(v, c));
        adj[v].push_back(make_pair(u, c));
    }

    if(k == 0) {
        dijkstra(1);
        out << dist[n] << '\n';
        return 0;
    }

    for(i = 0; i < k; i++) {
        dijkstra(special[i]);
        for(j = 0; j < k; j++) {
            kdist[i][j] = kdist[j][i] = dist[special[j]];
        }
    }

    dijkstra(1);
    for(nrcfg = (1 << k), j = 0; j < nrcfg; j++) {
        for(i = 0; i < k; i++) {
            dp[i][j] = INF;
        }
    }
    for(i = 0; i < k; i++) {
        dp[i][1 << i] = dist[special[i]];
    }
    for(j = 1; j < nrcfg; j++) {
        if(j & (j - 1) == 0) continue;
        for(i = 0; i < k; i++) {
            if(j & (1 << i)) {
                newcfg = j ^ (1 << i);
                for(t = 0; t < k; t++) {
                    if(newcfg & (1 << t)) {
                        dp[i][j] = min(dp[i][j], dp[t][newcfg] + kdist[t][i]);
                    }
                }
            }
        }
    }
    dijkstra(n);
    for(ans = INF, i = 0; i < k; i++) {
        ans = min(ans, dp[i][nrcfg - 1] + dist[special[i]]);
    }
    out << ans << '\n';
    return 0;
}