Cod sursa(job #2106528)

Utilizator infomaxInfomax infomax Data 15 ianuarie 2018 21:02:52
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.82 kb
#include <bits/stdc++.h>

#define f first
#define s second

using namespace std;

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

int n, m, k, c[20], j, d[2005], drum[20][2005], dp[33000][20], sol, x, y, z;
vector<pair<int, int> > a[2005];
priority_queue<pair<int, int> > pq;
bitset<2005> w;
const int inf = 1<<30;

void dijkstra(int nod, int bst[])
{
    w = 0;
    for(int i = 1; i <= n; ++ i) bst[i] = inf;
    bst[nod] = 0;
    pq.push({0, nod});
    vector<pair<int, int> > :: iterator it;
    while(!pq.empty())
    {
        x = pq.top().s;
        pq.pop();
        if(w[x]) continue;
        w[x]=1;
        for(it = a[x].begin(); it != a[x].end(); ++ it)
            if(bst[(*it).f] > bst[x]+(*it).s)
                bst[(*it).f] = bst[x]+(*it).s, pq.push({-bst[(*it).f], (*it).f});
    }
}

int main()
{
    F >> n >> m;
    F >> k;
    for(int i = 0; i < k; ++ i) F >> c[i];
    for(int i = 1; i <= m; ++ i)
    {
        F >> x >> y >> z;
        a[x].push_back({y, z});
        a[y].push_back({x, z});
    }
    dijkstra(1, d);
    if(!k)
    {
        G << d[n];
        return 0;
    }
    for(int i = 0; i < k; ++ i) dijkstra(c[i], drum[i]);
    for(int i = 1; i < (1<<k); ++ i)
    {
        for(j = 0; j < k && (1<<j)!= i; ++ j);
        if((1<<j) == i)
        {
            dp[i][j] = d[c[j]];
            continue;
        }
        for(j = 0; j < k; ++ j)
        {
            dp[i][j] = inf;
            if(i&(1<<j))
            {
                for(int h = 0; h < k; ++ h)
                    if(h != j && (1<<h)&i)
                        dp[i][j] = min(dp[i][j], dp[i^(1<<j)][h]+drum[h][c[j]]);
            }
        }
    }
    sol=inf;
    for(int i = 0; i < k; ++ i)
        sol=min(sol, dp[(1<<k)-1][i]+drum[i][n]);
    G << sol;
    return 0;
}