Cod sursa(job #1227697)

Utilizator Sanduleac_VladSanduleac Vllad Alexandru Sanduleac_Vlad Data 11 septembrie 2014 13:28:34
Problema Ubuntzei Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.62 kb
#include <cstdio>
#include <queue>
#include <vector>
using namespace std;

struct dr {
    short ot;
    short d;
};

struct L {
    short p, s;
    long d;
};

long N, M, K;
long f[2001];
long inv[2001];
long wh[21];
vector<dr> dist[2001];
long s, ff, d;
long df = 1000000000;
long viz[21][2001];
long dab[21][21];
long din[65536][21];
queue<L> q;

int main() {
    long i, j, k, prev;
    dr tmpd;
    L tmp;
    freopen("ubuntzei.in", "r", stdin);
    freopen("ubuntzei.out", "w", stdout);
    scanf("%ld %ld", &N, &M);
    scanf("%ld", &K);
    f[1] = f[N] = wh[0] = 1;
    wh[K + 1] = N;
    inv[0] = 1;
    inv[N] = K + 1;
    for(i = K; i; i--) {
        scanf("%ld", &j);
        f[j]++;
        tmp.p = tmp.s = j;
        tmp.d = 0;
        q.push(tmp);
        wh[i] = j;
        inv[j] = i;
    }
    for(i = M; i; i--) {
        scanf("%ld %ld %ld", &s, &ff, &d);
        tmpd.ot = ff;
        tmpd.d = d;
        dist[s].push_back(tmpd);
        tmpd.ot = s;
        dist[ff].push_back(tmpd);
    }
    for(i = 1; i <= K; i++) {
        tmp.s = tmp.p = wh[i];
        tmp.d = 0;
        q.push(tmp);
    }
    while(!q.empty()) {
        for(i = 0; i < dist[q.front().p].size(); i++) {
            tmp = q.front();
            tmp.p = dist[q.front().p][i].ot;
            tmp.d += dist[q.front().p][i].d;
            if(f[tmp.p] && (tmp.d < dab[inv[tmp.s]][inv[tmp.p]]) || (dab[inv[tmp.s]][inv[tmp.p]] == 0)) {
                q.push(tmp);
                dab[inv[tmp.s]][inv[tmp.p]] = tmp.d;
                dab[inv[tmp.p]][inv[tmp.s]] = tmp.d;
            } else if(!f[tmp.p] && !viz[inv[tmp.s]][tmp.p] || viz[inv[tmp.s]][tmp.p] > tmp.d) {
                q.push(tmp);
                viz[inv[tmp.s]][tmp.p] = tmp.d;
            }
        }
        q.pop();
    }
    for(i = 1; i <= K + 1; i++)
        din[0][i] = 1000000000;
    for(i = 1; i < 1 << K; i++) {
        for(j = 1; j <= K; j++)
            if((1 << (j - 1)) & i) {
                din[i][j] = 1000000000;
                prev = i & (~(1 << (j - 1))); // i fara j
                if(prev == 0) {
                    din[i][j] = dab[0][i];
                    continue;
                }
                for(k = 1; k <= K; k++)
                    if(((1 << (k - 1)) & prev) && din[prev][k] + dab[k][j] < din[i][j])
                        din[i][j] = din[prev][k] + dab[k][j];
            }
    }
    df = 1000000000;
    for(i = 1; i <= K; i++) {
        if(din[(1 << K) - 1][i] + dab[i][K + 1] < df)
            df = din[(1 << K) - 1][i] + dab[i][K + 1];
    }
    printf("%ld\n", df);
    return 0;
}