Cod sursa(job #2928580)

Utilizator tomaionutIDorando tomaionut Data 23 octombrie 2022 13:39:24
Problema Ubuntzei Scor 85
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.17 kb
#include <bits/stdc++.h>
#define INF 1e9

using namespace std;

ifstream fin("ubuntzei.in");
ofstream fout("ubuntzei.out");
int n, m, k, c[20], N, sol;
vector <pair <int, int> > a[2005];
priority_queue <pair <int, int> > Q;
bitset <2005> viz;
int dp[2005][2005];
int dpexp[16][1 << 16];
void Dijkstra(int start)
{   
    int x, cost;
    viz.reset();
    Q.push({ 0, start });
    dp[start][start] = 0;
    while (!Q.empty())
    {
        x = Q.top().second;
        Q.pop();
        if (viz[x] == 0)
        {
            viz[x] = 1;
            for (auto w : a[x])
            {
                if (dp[start][x] + w.first < dp[start][w.second])
                {
                    dp[start][w.second] = dp[start][x] + w.first;
                    Q.push({ -dp[start][w.second], w.second });
                }               
            }
        }
    }
}

int main()
{
    int i, j, cost, mask;
    fin >> n >> m >> k;
    N = (1 << k);
    for (i = 0; i < k; i++)
        fin >> c[i];

    while (m--)
    {
        fin >> i >> j >> cost;
        a[i].push_back({ cost, j });
        a[j].push_back({ cost, i });
    }

    for (i = 1; i <= n; i++)
        for (j = 1; j <= n; j++)
            dp[i][j] = INF;

    for (i = 1; i <= n; i++)
        Dijkstra(i);

    if (k == 0)
    {
        fout << dp[1][n] << "\n";
        return 0;
    }
    if (k == 1)
    {
        fout << dp[1][c[0]] + dp[c[0]][n] << "\n";
        return 0;
    }

    for (i = 0; i < k; i++)
        for (mask = 0; mask < N; mask++)
            dpexp[i][mask] = INF;

    for (i = 0; i < k; i++)
        dpexp[i][1 << i] = dp[1][c[i]];

    for (mask = 1; mask < N; mask++)
        for (i = 0; i < k; i++)
            if ((mask & (1 << i)))
            {
                for (j = 0; j < k; j++)
                    if ((mask & (1 << j)) == 0)
                        dpexp[j][mask | (1 << j)] = min(dpexp[j][mask | (1 << j)], dpexp[i][mask] + dp[c[i]][c[j]]);                  
            }

    sol = INF;
    for (i = 0; i < k; i++)
        sol = min(sol, dpexp[i][N - 1] + dp[c[i]][n]);

    fout << sol << "\n";

    

    return 0;
}