Cod sursa(job #3207773)

Utilizator PetraPetra Hedesiu Petra Data 26 februarie 2024 22:15:14
Problema Ubuntzei Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.28 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <cstring>

#define NMAX 2002
#define KMAX 15
#define inf 0x3f3f3f3f

using namespace std;

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

struct q_entry {
    int nod, val;
};

int n, m, k, c[(1<<KMAX)+2][NMAX], val[NMAX], cost[NMAX][NMAX];
// c[i][j] = costul minim sa ajungem din 1 in nodul j, parcurgand toate nodurile coresp. cu 1 din reprez binara a lui i
vector<q_entry> G[NMAX];
vector<int> oras;
priority_queue<q_entry> q;

bool operator< (q_entry a, q_entry b)
{
    return a.val > b.val;
}

void citire()
{
    fin >> n >> m >> k;

    for (int i = 0; i < k; i++)
    {
        int x;
        fin >> x;
        oras.push_back(x);
    }

    for (int i = 1; i <= m; i++)
    {
        int x, y, c;
        fin >> x >> y >> c;
        G[x].push_back({y, c});
        G[y].push_back({x, c});
    }
}

void dijkstra(int start)
{
    memset(val, 0x3f, sizeof(val));

    val[start] = 0;
    q.push({start, 0});
    while (!q.empty())
    {
        q_entry v = q.top();
        q.pop();

        if (v.val > val[v.nod]) continue;

        for (auto w : G[v.nod])
        {
            if (val[v.nod] + w.val < val[w.nod])
            {
                val[w.nod] = val[v.nod] + w.val;
                q.push({w.nod, val[w.nod]});
            }
        }
    }
}

int main()
{
    memset(c, 0x3f, sizeof(c));

    citire();

    if (k == 0)
    {
        dijkstra(1);
        fout << val[n];
        return 0;
    }

    for (int i = 0; i < k; i++)
    {
        dijkstra(oras[i]);
        for (int j = 0; j < k; j++)
            cost[i][j] = val[oras[j]];

        cost[i][k] = val[n];
        c[(1<<i)][i] = val[1];
    }

    for (int i = 0; i < (1<<k); i++)
    {
        for (int j = 0; j < k; j++)
        {
            if ((i & (1<<j)) == 0) continue;

            for (int t = 0; t < k; t++)
            {
                if ((i & (1<<t)) == 0)
                    c[i|(1<<t)][t] = min(c[i|(1<<t)][t], c[i][j] + cost[j][t]);
            }
        }
    }

    int sol = 0x3f3f3f3f;
    for (int i = 0; i < k; i++)
        sol = min(sol, c[(1<<k)-1][i] + cost[i][k]);

    fout << sol;

    return 0;
}