Cod sursa(job #1547775)

Utilizator Burbon13Burbon13 Burbon13 Data 9 decembrie 2015 21:13:28
Problema Ubuntzei Scor 20
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.4 kb
#include <cstdio>
#include <vector>
#include <queue>
#include <cstring>
#include <iostream>
#include <bitset>
#define f first
#define s second
using namespace std;

const int inf = 0x3f3f3f3f;
const int nmx = 2002;
const int kmx = 16;

int n,m,k,l[kmx][nmx],oras[kmx];
int dp[1 << kmx][nmx];
vector <pair<int,int> > g[nmx];
priority_queue <pair<int,int> > q;

void citire() {
    scanf("%d %d", &n, &m);
    scanf("%d", &k);

    for(int i = 1; i <= k; ++i)
        scanf("%d", &oras[i]);

    int nod1, nod2, cost;
    for(int i = 1; i <= m; ++i) {
        scanf("%d %d %d", &nod1, &nod2, &cost);
        g[nod1].push_back(make_pair(nod2,cost));
        g[nod2].push_back(make_pair(nod1,cost));
    }
}

void dijkstra(int nr_oras, int nod_start) { /// l[i][j] distanta de la orasul i la nodul j
    l[nr_oras][nod_start] = 0;
    q.push(make_pair(0,nod_start));
    while(not q.empty()) {
        int nod = q.top().second;
        q.pop();
        for(vector<pair<int,int> >::iterator it = g[nod].begin(); it != g[nod].end(); ++it)
            if(l[nr_oras][it->first] > l[nr_oras][nod] + it->second) {
                l[nr_oras][it->first] = l[nr_oras][nod] + it->second;
                q.push(make_pair(-l[nr_oras][it->first],it->first));
            }
    }
}

bool pp(int nr){
    for(int i = 1; i <= nr; i *= 2)
        if(i == nr)
            return 1;
    return 0;
}

void dinamica() { /// dp[i][j] costul ptr drumul min format din i orase pana in orasul j
    if(k == 0) {
        printf("%d\n", l[0][n]);
        return;
    }

    for(int i = 0; i < k; ++i)
        dp[1 << i][i] = l[0][oras[i+1]];

    for(int t = 2; t < 1 << k ; ++t){
        if(pp(t))
            continue;
        for(int p = 0; p < k; ++p)
            for(int j = 0; j < k; ++j)
                if(p != j && (dp[t][p] > dp[t - (1 << p)][j] + l[j][oras[p+1]] || not dp[t][p]))
                    dp[t][p] = dp[t - (1 << p)][j] + l[j][oras[p+1]];
    }

    int miin = inf;
    for(int i = 0; i < k; ++i)
        if(miin > dp[(1 << k) - 1][i] + l[i][n])
            miin = dp[(1 << k) - 1][i] + l[i][n];
    printf("%d\n", miin);
}

int main() {
    freopen("ubuntzei.in", "r", stdin);
    freopen("ubuntzei.out", "w", stdout);
    citire();
    memset(l,inf,sizeof(l));
    oras[0] = 1;
    for(int i = 0; i <= k; ++i)
        dijkstra(i,oras[i]);

    dinamica();

    return 0;
}