Cod sursa(job #2100929)

Utilizator abccnuCamelia Zalum abccnu Data 6 ianuarie 2018 16:27:49
Problema Ubuntzei Scor 20
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.65 kb
#include <iostream>
#include <fstream>
#include <queue>
#include <vector>

using namespace std;

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

const int NMAX = 2000 + 5;
const int MMAX = 10000 + 5;
const int  oo = 1 << 30;

int N, M, K, c[NMAX];

int rez[1<<10][NMAX];
int dp[NMAX][NMAX];

struct Elem
{
    int nod;
    int cost;

    bool operator<(const Elem &arg)const
    {
        return cost > arg.cost;
    }

    Elem (int _nod = 0, int _cost = 0)
    {
        nod = _nod;
        cost = _cost;
    }
};

priority_queue <Elem> q;
vector < Elem > gr[NMAX];

void read()
{
    int x, y, z;

    fin >> N >> M;
    fin >> K;
    for (int i = 1; i <= K; ++i)
        fin >> c[i];

    Elem aux;

    for(int i = 1; i <= M; ++i)
    {
        fin >> x >> y >> z;

        aux.nod = y;
        aux.cost = z;

        gr[x].push_back(aux);

        aux.nod = x;

        gr[y].push_back(aux);
    }
}

int Dijkstra(int poz, int x)
{
    Elem aux, alt;

    for (int i=1;i<=N;i++) dp[poz][i]=oo;

    dp[poz][x] = 0;

    alt.nod = x;
    alt.cost = 0;

    q.push(Elem(x, 0));

    while (!q.empty())
    {
        alt = q.top();
        q.pop();

        if (alt.cost == dp[poz][alt.nod])
        {
            for (vector <Elem> ::iterator it=gr[alt.nod].begin();it!=gr[alt.nod].end();it++)
            {
                aux = *it;
                if (dp[poz][aux.nod] > dp[poz][alt.nod] + aux.cost)
                {
                    dp[poz][aux.nod] = dp[poz][alt.nod] + aux.cost;
                    aux.cost = dp[poz][aux.nod];
                    q.push(Elem(aux.nod, aux.cost));

                }
            }
        }

    }

}


int main()
{
    read();
    Dijkstra(0, 1);


    if (K == 0) fout << dp[0][N];
    else{
            for (int i = 1; i <= K; ++i) Dijkstra(i, c[i]);

            for (int i = 1; i <= N; ++i)
                for (int j = 1; j <= K; ++j)
                    rez[i][j] = oo;

            for (int i = 1; i <= K; ++i) rez[1<<(i-1)][i] = dp[0][c[i]];

            for (int j =1; j < (1<<K); ++j)
            {
                for (int i = 1; i<=K; ++i)
                {
                    for (int aux = 1; aux <= K; ++aux)
                    {
                        if (aux != i and j&(1<<(aux-1)))
                            rez[j][i] = min(rez[j][i], rez[j - 1<<(i-1)][aux] + dp[aux][c[i]]);

                    }
                }
            }

            int sol = oo;
            for (int j = 1; j<=K ; ++j)sol = min(sol, rez[(1<<K) -1][j] + dp[j][N]);
            fout << sol;
    }

    return 0;
}