Cod sursa(job #2172296)

Utilizator ionutpop118Pop Ioan Cristian ionutpop118 Data 15 martie 2018 15:58:29
Problema Ubuntzei Scor 5
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.15 kb
#include <cstdio>
#include <queue>
#include <vector>
#include <cstring>
using namespace std;
const int NMAX = 2000;
struct drum
{
    int x, dist;
}; vector <drum> g[NMAX + 5]; drum nou;
priority_queue <int, vector <int>, greater <int>> pq;
bool viz[NMAX + 5];
int a[20][NMAX + 5];
int d[33000][20], v[20];
int main()
{
    freopen("ubuntzei.in", "r", stdin);
    freopen("ubuntzei.out", "w", stdout);
    int n, m, k, x, y, cn, dist, ans;
    scanf("%d %d %d", &n, &m, &k);
    for (int i = 1; i <= k; ++i)
        scanf("%d", &v[i]);
    for (int i = 1; i <= m; ++i)
    {
        scanf("%d %d %d", &x, &y, &dist);
        nou.dist = dist; nou.x = y;
        g[x].push_back(nou);
        nou.x = x;
        g[y].push_back(nou);
    }

    memset(a, -1, sizeof(a));
    /// Djikstra din "1"
    pq.push(1); a[0][1] = 0;
    while (!pq.empty())
    {
        x = pq.top(); pq.pop();
        if (viz[x] == 1)
            continue;
        viz[x] = 1;
        for (int i = 0; i < g[x].size(); ++i)
        {
            y = g[x][i].x; dist = g[x][i].dist;
            if (a[0][y] == -1 || dist + a[0][x] < a[0][y])
            {
                a[0][y] = a[0][x] + dist;
                pq.push(y);
            }
        }
    }
    memset(viz, 0, sizeof(viz));
    /// Djikstra din "n"
    pq.push(n); a[k + 1][n] = 0;
    while (!pq.empty())
    {
        x = pq.top(); pq.pop();
        if (viz[x] == 1)
            continue;
        viz[x] = 1;
        for (int i = 0; i < g[x].size(); ++i)
        {
            y = g[x][i].x; dist = g[x][i].dist;
            if (a[k + 1][y] == -1 || dist + a[k + 1][x] < a[k + 1][y])
            {
                a[k + 1][y] = a[k + 1][x] + dist;
                pq.push(y);
            }
        }
    }
    memset(viz, 0, sizeof(viz));
    /// Djikstra din cele k orase
    for (int i = 1; i <= k; ++i)
    {
        pq.push(v[i]); a[i][v[i]] = 0;
        while (!pq.empty())
        {
            x = pq.top(); pq.pop();
            if (viz[x] == 1)
                continue;
            viz[x] = 1;
            for (int i = 0; i < g[x].size(); ++i)
            {
                y = g[x][i].x; dist = g[x][i].dist;
                if (a[i][y] == -1 || dist + a[i][x] < a[i][y])
                {
                    a[i][y] = a[i][x] + dist;
                    pq.push(y);
                }
            }
        }
        memset(viz, 0, sizeof(viz));
    }
    /// Dinamica
    for (int i = 1; i <= k; ++i)
        d[1 << (i - 1)][i] = a[0][v[i]];
    for (int c = 1; c < (1 << k); ++c)
        for (int i = 1; i <= k; ++i)
            if (c & (1 << (i - 1)) != 0)
                for (int j = 1; j <= k; ++j)
                    if (c & (1 << (j - 1)) == 0)
                    {
                        cn = c + (1 << (j - 1));
                        if(d[cn][j] == 0 || d[c][i] + a[i][v[j]] < d[cn][j])
                            d[cn][j] = d[c][i] + a[i][v[j]];
                    }
    ans = d[(1 << k) - 1][1] + a[k + 1][1];
    for (int i = 2; i <= k; ++i)
        ans = min (ans, d[(1 << k) - 1][i] + a[k + 1][i]);
    printf("%d\n", ans);
    return 0;
}