Mai intai trebuie sa te autentifici.

Cod sursa(job #1307340)

Utilizator thewildnathNathan Wildenberg thewildnath Data 1 ianuarie 2015 23:13:01
Problema Ubuntzei Scor 65
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.98 kb
#include <cstdio>
#include <vector>
#include <queue>

using namespace std;

const int NMAX = 2000;
const int KMAX = 15;


struct drum
{
    int dest;
    int lung;

    drum (int dest = 0, int lung = 0)
    {
        this->dest = dest;
        this->lung = lung;
    }
};

int n, m, k, tata;
int dist[KMAX + 1][NMAX + 1], oras[NMAX + 1], cost[(1 << (KMAX + 1))][NMAX + 1];
bool viz[(1 << (KMAX + 1))][NMAX + 1];

vector <drum> v[NMAX + 1];

struct cmp
{
    bool operator () (const drum &a, const drum &b)
    {
        return a.lung > b.lung;
    }
};

priority_queue <drum, vector <drum>, cmp> hp;


void dijkstra (int nod)
{
    int fiu;

    hp.push (drum (nod, 0));

    while (!hp.empty ())
    {
        nod = hp.top ().dest;
        hp.pop ();

        for (int i = 0; i < v[nod].size (); ++i)
        {
            fiu = v[nod][i].dest;

            if (!dist[tata][fiu] || dist[tata][fiu] > dist[tata][nod] + v[nod][i].lung)
            {
                dist[tata][fiu] = dist[tata][nod] + v[nod][i].lung;
                hp.push (drum (fiu, dist[tata][fiu]));
            }
        }
    }
}

struct stare
{
    int st;
    int ultim;

    stare (int st = 0, int ultim = 0)
    {
        this->st = st;
        this->ultim = ultim;
    }
};

queue <stare> q;

void din ()
{
    stare a;

    for (int i = 0; i < k; ++i)
    {
        cost[(1 << i)][i] = dist[k][oras[i]];
        viz[(1 << i)][i] = true;
        q.push (stare ((1 << i), i));
    }

    while (!q.empty ())
    {
        a = q.front ();
        q.pop ();

        for (int i = 0; i < k; ++i)
        {
            if ((a.st & (1 << i)) == 0)
            {
                int x = a.st + (1 << i);

                if (!cost[x][i] || cost[x][i] > cost[a.st][a.ultim] + dist[a.ultim][oras[i]])
                {
                    cost[x][i] = cost[a.st][a.ultim] + dist[a.ultim][oras[i]];

                    if(!viz[x][i])
                    {
                        viz[x][i] = true;
                        q.push (stare (x, i));
                    }
                }
            }
        }

        viz[a.st][a.ultim] = false;
    }
}

int main ()
{
    freopen ("ubuntzei.in", "r", stdin);
    freopen ("ubuntzei.out", "w", stdout);

    int x, y, c;

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

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

    for (int i = 0; i < m; ++i)
    {
        scanf ("%d%d%d", &x, &y, &c);

        v[x].push_back (drum (y, c));
        v[y].push_back (drum (x, c));
    }

    for (int i = 0; i < k; ++i)
    {
        tata = i;
        dijkstra (oras[i]);
    }

    tata = k;
    dijkstra (1);

    din ();

    int sol = 2000000000;

    if (k == 0)
        sol = dist[0][n];

    for (int i = 0; i < k; ++i)
        if (cost[(1 << k) - 1][i] + dist[i][n] < sol)
            sol = cost[(1 << k) - 1][i] + dist[i][n];

    printf ("%d\n", sol);

    return 0;
}