Cod sursa(job #2952823)

Utilizator stefandutastefandutahoria stefanduta Data 10 decembrie 2022 01:11:06
Problema Ubuntzei Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.36 kb
#include <fstream>
#include <vector>
#include <queue>
#define NMAX 2005
#define MMAX 10005

using namespace std;

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

struct ok{
    int vec, cost;
};

struct ok2{
    int nod, dist;
    bool operator < (ok2 a) const
    {
        return dist > a.dist;
    }
};

int c[NMAX];
vector <ok> adj[NMAX];
priority_queue <ok2> q;
int dist[NMAX][NMAX];
const int INF = 1e9 + 5;
const int PMAX = 132000;
const int KMAX = 18;
int dp[PMAX][KMAX];

int main()
{
    int n, m, k, i, j, a, b, x, l, z;
    in >> n >> m;
    in >> k;
    for (i = 1; i <= k; ++i)
        in >> c[i];
    c[0] = 1;
    c[k + 1] = n;

    for (i = 1; i <= m; ++i)
    {
        in >> a >> b >> x;
        adj[a].push_back({b, x});
        adj[b].push_back({a, x});
    }

    for (i = 1; i < NMAX; ++i)
    {
        for (j = 1; j < NMAX; ++j)
            dist[i][j] = INF;
    }

    for (z = 0; z <= k + 1; ++z)
    {
        j = c[z];
        q.push({j, 0});
        dist[j][j] = 0;
        while(!q.empty())
        {
            int nod = q.top().nod;
            int d = q.top().dist;
            q.pop();
            if (d == dist[j][nod])
            {
                for (i = 0; i < adj[nod].size(); ++i)
                {
                    int vec = adj[nod][i].vec;
                    int cost = adj[nod][i].cost;
                    if (dist[j][vec] > dist[j][nod] + cost)
                    {
                        dist[j][vec] = dist[j][nod] + cost;
                        q.push({vec, dist[j][nod] + cost});
                    }
                }
            }
        }
        dist[j][j] = INF;
    }

    int t =  1 << (k + 2);
    for (i = 0; i < t; ++i)
    {
        for (j = 0; j <= k + 1; ++j)
        {
            dp[i][j] = INF;
        }
    }

    dp[1][0] = 0;

    for (i = 1; i < t; i = i + 2)
    {
        for (j = 0; j <= k + 1; ++j)
        {
            if (i & (1 << j))
            {
                for (l = 0; l <= k + 1; ++l)
                {
                    if (dp[i][j] > dp[i ^ (1 << j)][l] + dist[c[l]][c[j]])
                    {
                        dp[i][j] = dp[i ^ (1 << j)][l] + dist[c[l]][c[j]];
                    }
                }
            }
        }
    }
    out << dp[t - 1][k + 1];

    return 0;
}