Cod sursa(job #1513595)

Utilizator lacraruraduRadu Matei Lacraru lacraruradu Data 29 octombrie 2015 19:06:34
Problema Ubuntzei Scor 55
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.4 kb
#include <fstream>

using namespace std;

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

#define N 2005
#define M 10005
#define INF (1 << 31) - 1

int lst[N], vf[2 * M], urm[2 * M], cost[2 * M], nr;
int n, m, k;
int h[N], poz[N], nh;
int d[N];
int kvf[20], pozk[N], nk;

int lst2[20], vf2[450], urm2[450], cost2[450], nr2;
int e[1 << 20][20];

void schimba(int i1, int i2)
{
    int aux = h[i1];
    h[i1] = h[i2];
    h[i2] = aux;
    poz[h[i1]] = i1;
    poz[h[i2]] = i2;
}

void urca(int i)
{
    while(i >= 2 && d[h[i]] < d[h[i / 2]])
    {
        schimba(i, i / 2);
        i /= 2;
    }
}

void coboara(int i)
{
    int bun = i, fs = 2 * i, fd = 2 * i + 1;
    if(fs <= nh && d[h[fs]] < d[h[bun]])
        bun = fs;
    if(fd <= nh && d[h[fd]] < d[h[bun]])
        bun = fd;
    if(i != bun)
    {
        schimba(i, bun);
        coboara(bun);
    }
}

void adauga(int x)
{
    h[++nh] = x;
    poz[x] = nh;
    urca(nh);
}

void sterge(int i)
{
    poz[h[i]] = 0;
    schimba(i, nh);
    nh--;
    urca(i);
    coboara(i);
}

void dijkstra(int x)
{
    for(int i = 1; i <= n; i++)
        poz[i] = 0;

    for(int i = 1; i <= n; i++)
        d[i] = INF;
    d[x] = 0;
    adauga(x);

    while(nh)
    {
        x = h[1];
        sterge(1);

        for(int i = lst[x]; i; i = urm[i])
        {
            int y = vf[i];
            int c = cost[i];

            if(d[x] + c < d[y])
            {
                d[y] = d[x] + c;

                if(poz[y] == 0)
                    adauga(y);
                else
                    urca(poz[y]);
            }
        }
    }
}

int main()
{
    in >> n >> m;

    in >> k;
    kvf[++nk] = 1;
    pozk[1] = nk;
    kvf[++nk] = n;
    pozk[n] = nk;
    for(int i = 1; i <= k; i++)
    {
        int x;
        in >> x;
        kvf[++nk] = x;
        pozk[x] = nk;
    }

    for(int i = 1; i <= m; i++)
    {
        int x, y, c;
        in >> x >> y >> c;

        vf[++nr] = y;
        cost[nr] = c;
        urm[nr] = lst[x];
        lst[x] = nr;
        vf[++nr] = x;
        cost[nr] = c;
        urm[nr] = lst[y];
        lst[y] = nr;
    }

    for(int i = 1; i <= nk; i++)
    {
        dijkstra(kvf[i]);
        for(int j = 1; j <= nk; j++)
        {
            if(j == i || d[j] == INF)
                continue;

            vf2[++nr2] = kvf[i];
            cost2[nr2] = d[kvf[j]];
            urm2[nr2] = lst2[kvf[j]];
            lst2[kvf[j]] = nr2;
        }
    }

    for(int i = 1; i <= (1 << nk) - 1; i += 2)
        for(int j = 0; j <= nk - 1; j++)
            e[i][j] = INF;
    e[1][0] = 0;

    for(int i = 3; i <= (1 << nk) - 1; i += 2)
        for(int j = 1; j <= n - 1; j++)
        {
            e[i][j] = INF;
            if(!(i & (1 << j)))
                continue;
            for(int k = lst2[kvf[j + 1]]; k; k = urm2[k])
                if(i & (1 << (pozk[vf2[k]] - 1)) && e[i - (1 << j)][pozk[vf2[k]] - 1] != INF && e[i][j] > e[i - (1 << j)][pozk[vf2[k]] - 1] + cost2[k])
                    e[i][j] = e[i - (1 << j)][pozk[vf2[k]] - 1] + cost2[k];
        }

    /*for(int i = 1; i <= nk; i++)
    {
        out << kvf[i] << ' ';
        for(int j = lst2[kvf[i]]; j; j = urm2[j])
            out << vf2[j] << ' ';
        out << '\n';
    }*/

    out << e[(1 << nk) - 1][1] << '\n';
    return 0;
}