Cod sursa(job #2145174)

Utilizator andru47Stefanescu Andru andru47 Data 27 februarie 2018 10:19:25
Problema Ubuntzei Scor 55
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.99 kb
#include <bits/stdc++.h>
#define inf 1000000000
#define per pair<int , int>
using namespace std;
const int NMAX = 2005;
int n, m, k, oras[NMAX], drum[NMAX][NMAX], dp[32800][NMAX];
priority_queue <per, vector <per>, greater<per> > pq;
vector <per> g[NMAX];
inline void dijkstra(int nod, int dr[NMAX])
{
    for (int i = 1; i<=n; ++i)
        if (i != nod)
            dr[i] = inf;
    pq.push({0, nod});
    while (!pq.empty())
    {
        per top = pq.top();
        pq.pop();
        if (dr[top.second] != top.first)
            continue;
        for (auto &it : g[top.second])
            if (dr[it.first] > top.first + it.second)
            {
                dr[it.first] = top.first + it.second;
                pq.push({dr[it.first], it.first});
            }
    }
    return ;
}
int main()
{
    freopen("ubuntzei.in", "r", stdin);
    freopen("ubuntzei.out", "w", stdout);

    scanf("%d %d\n", &n, &m);
    scanf("%d", &k);
    for (int i = 1; i<=k; ++i)
        scanf("%d", &oras[i]);
    for (int i = 1; i<=m; ++i)
    {
        int x, y, c;
        scanf("%d %d %d", &x, &y, &c);
        g[x].push_back({y, c});
        g[y].push_back({x, c});
    }
    dijkstra(1, drum[1]);
    if (k == 0)
    {
        printf("%d\n", drum[1][n]);
        return 0;
    }
    for (int i = 1; i<=k; ++i)
        dijkstra(oras[i], drum[oras[i]]);

    for (int i = 1; i<=k; ++i)
        for (int j = 0; j < (1 << k); ++j)
            dp[j][i] = inf;
    for (int i = 1; i<=k; ++i)
        dp[1 << (i - 1)][i] = drum[1][oras[i]];
    for (int i = 2; i < (1 << k); ++i)
        for (int j = 1; j <= k; ++j)
            if (i & (1 << (j - 1)))
                for (int kk = 1; kk <= k; ++kk)
                    dp[i][j] = min(dp[i][j], dp[i ^ (1 << (j - 1))][kk] + drum[oras[j]][oras[kk]]);
    int masca = (1 << k) - 1, solmin = inf;
    for (int i = 1; i<=k; ++i)
        solmin = min(solmin, dp[masca][i] + drum[oras[i]][n]);
    printf("%d\n", solmin);

    return 0;
}