Cod sursa(job #2921438)

Utilizator andreimocianAndrei Mocian andreimocian Data 31 august 2022 02:10:12
Problema Ubuntzei Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.5 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>

using namespace std;

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

struct el
{
    int nod, cost;
    bool operator < (const el &A) const{
        return cost > A.cost;
    }
};

const int INF = 1e9;
int n, m, k, sol;
int a[2005], dp[2005], dps[(1 << 17) + 3][20];
int cost[20][20];
vector < el > L[2005];
priority_queue < el > Q;

void citire()
{
    int x, y, z, oras;
    el w;
    fin >> n >> m;
    fin >> k;
    for(int i = 1; i <= k; i++)
    {
        fin >> a[i];
    }
    a[0] = 1;
    a[++k] = n;
    for(int i = 1; i <= m; i++)
    {
        fin >> x >> y >> z;
        w.nod = y;
        w.cost = z;
        L[x].push_back(w);
        w.nod = x;
        L[y].push_back(w);
    }
}

void Dijkstra()
{
    el w2;
    while(!Q.empty())
    {
        el w = Q.top();
        Q.pop();
        for(auto it : L[w.nod])
        {
            if(dp[it.nod] > dp[w.nod] + it.cost)
            {
                dp[it.nod] = dp[w.nod] + it.cost;
                w2.nod = it.nod;
                w2.cost = dp[it.nod];
                Q.push(w2);
            }
        }
    }
}

void construire()
{
    el E;
    for(int i = 0; i <= k; i++)
    {
        for(int j = 1; j <= n; j++)
            dp[j] = INF;
        dp[a[i]] = 0;
        E.nod = a[i];
        E.cost = 0;
        Q.push(E);
        Dijkstra();
        for(int j = 0; j <= k; j++)
        {
            cost[i][j] = dp[a[j]];
        }
    }
}

void solve()
{
    int stare, kp;
    sol = INF;
    kp = (1 << k);
    for(stare = 1; stare < kp; stare++)
    {
        for(int j = 0; j <= k; j++)
        {
            dps[stare][j] = INF;
        }
    }
    for(int i = 0; i <= k; i++)
    {
        dps[1 << i][i] = cost[0][i];
    }
    for(stare = 1; stare < kp; stare++)
    {
        for(int i = 0; i <= k; i++)
        {
            if((stare & (1 << i)))
            {
                for(int j = 0; j <= k; j++)
                {
                    if(!(stare & (1 << j)))
                    {
                        dps[stare | (1 << j)][j] = min(dps[stare | (1 << j)][j], dps[stare][i] + cost[i][j]);
                    }
                }
            }
        }
    }
    for(int i = 0; i < k; i++)
    {
        sol = min(sol, dps[kp-1][i] + cost[i][k]);
    }
    fout << sol;
}

int main()
{
    citire();
    construire();
    solve();
    return 0;
}