Cod sursa(job #1515795)

Utilizator depevladVlad Dumitru-Popescu depevlad Data 2 noiembrie 2015 10:17:04
Problema Ubuntzei Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.36 kb
#include <fstream>
#include <vector>
#include <algorithm>
#include <queue>
#include <tuple>

using namespace std;

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

const int MAX_N = 2000;
const int MAX_K = 15;
const int MAX_CFG = 1 << (MAX_K + 2);
const int INF = 0x7fffffff;

class pqCompare {
public:
    bool operator ()(const pair < int, int > &A, const pair < int, int > &B) {
        return get<1>(A) > get<1>(B);
    }
};

int n, m, k;
int X[3 + MAX_K];
bool isX[1 + MAX_N];
int Dist[1 + MAX_N];
int C[1 + MAX_K][1 + MAX_K];
int D[MAX_CFG];
vector < int > A[1 + MAX_N];
priority_queue < pair < int, int >, vector < pair < int, int >, pqCompare > Q;

void initDijkstra(int s) {
    int i;
    for(i = 1; i <= n; i++) Dist[i] = 0;
    Dist[s] = 0;
    Q.clear();
    Q.push(make_pair(s, 0));
}

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

    while(!Q.empty()) {
        u = get<0>(Q.top());
        d = get<1>(Q.top());

        if(Dist[u] != d || (isX[u] && u != s)) continue;
        for(auto i : A[u]) {
            v = get<0>(i);
            c = get<1>(i);
            if(D[v] > d + c) {
                D[v] = d + c;
                Q.push(make_pair(v, d + c));
            }
        }
    }
}

void calcDistances() {
    int i, j;
    for(i = 1; i <= k; i++) {
        dijkstra(i);
        for(j = 1; j <= k; j++) {
            C[i][j] = C[j][i] = Dist[X[j]];
        }
    }
}

int getMinPath() {
    int i, j;

    for(i = 1; i < (1 << k); i++) {
        if((i & (i-1)) == 0) D[i] = 0;
        else D[i] = INF;
    }
    for(i = 1; i < (1 << k); i++) {
        for(j = 0; j < k; j++) {
            if(i & (1 << j)) {
                for(auto t : A[j]) {
                    if(i & (1 << get<0>(t))) {
                        D[i] = min(D[i], D[i] - (1 << j) + get<1>(i));
                    }
                }
            }
        }
    }
}

int main() {
    int i, u, v, c;

    in >> n >> m >> k;
    X[1] = 1;
    for(i = 2; i <= k+1; i++) {
        in >> X[i];
        isX[i] = 1;
    }
    X[k+2] = n;
    k += 2;
    isX[1] = isX[n+1] = 1;

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

    calcDistances();
    getMinPath();

    out << D[(1 << k) - 1];
    return 0;
}