Cod sursa(job #1625137)

Utilizator Sanduleac_VladSanduleac Vllad Alexandru Sanduleac_Vlad Data 2 martie 2016 17:01:01
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.48 kb
#include <cstdio>
#include <vector>
#include <queue>
using namespace std;

struct L {
    int pos;
    int ccrt;
    bool operator<(const L &other) const {
        return ccrt > other.ccrt;
    }
    L(int _pos, int _ccrt) {
        pos = _pos;
        ccrt = _ccrt;
    }
    L() {}
};

int N, M;
int K;
int pos[16];
int d[20][20];
vector<int> viz;
vector<vector<pair<int, int> > > con;
priority_queue<L> q;

void bfs(int start, int as) {
    int i;
    fill(viz.begin(), viz.end(), 0);
    q.push(L(start, 1));
    while(!q.empty()) {
        L tmp, crt;
        crt = q.top();
        q.pop();
        if(viz[crt.pos] == 0) {
            viz[crt.pos] = crt.ccrt;
        } else {
            continue;
        }
        for(i = 0; i < con[crt.pos].size(); i++) {
            if(viz[con[crt.pos][i].first] == 0) {
                tmp = crt;
                tmp.pos = con[crt.pos][i].first;
                tmp.ccrt += con[crt.pos][i].second;
                q.push(tmp);
            }
        }
    }
    d[as][0] = viz[0] - 1;
    for(i = 1; i <= K; i++) {
        d[as][i] = viz[pos[i]] - 1;
    }
    d[as][K + 1] = viz[N - 1] - 1;
}

int viz2[70001][20];

int main() {
    int i, j, k;
    freopen("ubuntzei.in", "r", stdin);
    freopen("ubuntzei.out", "w", stdout);
    scanf("%d %d", &N, &M);
    scanf("%d", &K);
    for(i = 1; i <= K; i++) {
        scanf("%d", &pos[i]);
        pos[i]--;
    }
    con.resize(N, vector<pair<int, int> >());
    for(i = 1; i <= M; i++) {
        int a, b, c;
        scanf("%d %d %d", &a, &b, &c);
        a--;
        b--;
        con[a].push_back(make_pair(b, c));
        con[b].push_back(make_pair(a, c));
    }
    viz.resize(N, 0);
    bfs(0, 0);
    bfs(N -1, K + 1);
    for(i = 1; i <= K; i++) {
        bfs(pos[i], i);
    }
    for(i = 1; i < 1 << K; i++) {
        for(j = 1; j <= K; j++) if((1 << (j - 1)) & i) {
            for(k = 0; k <= K; k++) if((k == 0 && (1 << (j - 1)) == i) || (j != k && (1 << (k - 1) & i))) {
                if(viz2[i][j] == 0 || viz2[~((~i) | (1 << (j - 1)))][k] + d[k][j] < viz2[i][j]) {
                    viz2[i][j] = viz2[~((~i) | (1 << (j - 1)))][k] + d[k][j];
                }
            }
        }
    }
    i = (1 << K) - 1;
    j = K + 1;
    for(k = 1; k <= K; k++) {
        if(viz2[i][j] == 0 || viz2[i][k] + d[k][j] < viz2[i][j]) {
            viz2[i][j] = viz2[i][k] + d[k][j];
        }
    }
    if(K == 0) {
        viz2[((1 << K) - 1)][K + 1] = d[0][1];
    }
    printf("%d\n", viz2[((1 << K) - 1)][K + 1]);
    return 0;
}