Cod sursa(job #2986138)

Utilizator toma_ariciuAriciu Toma toma_ariciu Data 27 februarie 2023 19:45:15
Problema Ubuntzei Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.19 kb
/// Preset de infoarena
#include <fstream>
#include <vector>
#include <queue>

using namespace std;

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

const int maxN = 2005, inf = 0x3f3f3f3f;
int n, m, k, v[20], costs[20][20], dist[maxN], dp[(1 << 20) + 5][20];
bool used[maxN];
struct heapNode {
    int nod, cost;
    bool operator < (const heapNode &other) const {
        return cost > other.cost;
    }
};
priority_queue <heapNode> heap;
vector <heapNode> G[maxN];

void dijkstra(int s)
{
    for(int i = 1; i <= n; i++)
        dist[i] = inf, used[i] = 0;
    dist[s] = 0;
    heap.push({s, 0});
    while(!heap.empty())
    {
        auto curr = heap.top();
        heap.pop();
        if(used[curr.nod])
            continue;
        used[curr.nod] = 1;
        for(auto nxt : G[curr.nod])
        {
            if(dist[curr.nod] + nxt.cost >= dist[nxt.nod])
                continue;
            dist[nxt.nod] = dist[curr.nod] + nxt.cost;
            heap.push({nxt.nod, dist[nxt.nod]});
        }
    }
}

int main()
{
    fin >> n >> m;
    v[0] = 1;
    fin >> k;
    for(int i = 1; i <= k; i++)
        fin >> v[i];
    v[++k] = n;
    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});
    }
    for(int i = 0; i <= k; i++)
    {
        dijkstra(v[i]);
        for(int j = 0; j <= k; j++)
            costs[i][j] = dist[v[j]];
    }
    for(int config = 0; config < (1 << (k + 1)); config++)
        for(int i = 0; i <= k; i++)
            dp[config][i] = inf;
    dp[1][0] = 0;
    for(int config = 1; config < (1 << (k + 1)); config++)
    {
        for(int nod = 0; nod <= k; nod++)
        {
            if((config & (1 << nod)) == 0)
                continue;
            for(int nxt = 0; nxt <= k; nxt++)
            {
                if((config & (1 << nxt)) == 0)
                    continue;
                int old_config = config ^ (1 << nxt);
                dp[config][nxt] = min(dp[config][nxt], dp[old_config][nod] + costs[nod][nxt]);
            }
        }
    }
    fout << dp[(1 << (k + 1)) - 1][k];
    return 0;
}