Cod sursa(job #2720018)

Utilizator chriss_b_001Cristian Benghe chriss_b_001 Data 10 martie 2021 15:25:56
Problema Ubuntzei Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.27 kb
#include <iostream>
#include <fstream>
#include <queue>
#include <vector>

using namespace std;

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

const int NMAX = 2001,
          INF = 999999999,
          FMAX = 17;

int d[NMAX], N, M, K, Friend[FMAX];
bool viz[NMAX];
int Cost[FMAX][FMAX];

class Comp
{
public:
    bool operator()(const int &a, const int &b)
    {
        return d[a] > d[b];
    }
};

priority_queue<int, vector<int>, Comp> Q;
vector<pair<int, int> > L[NMAX];

int dp[1 << 17][17];

void citire()
{
    f >> N >> M >> K;
    for(int i = 1; i <= K; ++i)
        f >> Friend[i];
    for(int i = 1; i <= M; ++i)
    {
        int x, y, c;
        f >> x >> y >> c;
        L[x].push_back({y, c});
        L[y].push_back({x, c});
    }
}

void Dijkstra(int p)
{
    for(int i = 1; i <= N; ++i)
        d[i] = INF;
    Q.push(p);
    d[p] = 0;
    viz[p] = 1;
    while(!Q.empty())
    {
        int vf = Q.top();
        Q.pop();
        viz[vf] = 0;
        for(auto i : L[vf])
        {
            int nod  = i.first,
                cost = i.second;
            if(d[nod] > cost + d[vf])
            {
                d[nod] = cost + d[vf];
                if(!viz[nod])
                {
                    viz[nod] = 1;
                    Q.push(nod);
                }
            }
        }

    }
}


int main()
{
    citire();
    Friend[0] = 1;
    Friend[K + 1] = N;
    for(int i = 0; i <= K + 1; ++i)
    {
        Dijkstra(Friend[i]);

        for(int j = 0; j <= K + 1; ++j)
            Cost[i][j] = d[Friend[j]];
    }
    if(K == 0)
    {
        g << Cost[0][1];
        return 0;
    }

    for(int i = 0; i <= K + 1; i++)
        for(int j = 0; j <= (1 << (K + 1)); j++)
            dp[j][i] = INF;

    for(int j = 1; j <= K; j++)
        dp[(1 << j) + 1][j] = Cost[0][j];

    for(int i = 1; i < 1 << (K + 1); i++)
        for(int j = 0; j <= K; j++)
            if(i & (1 << j))
                for(int k = 1; k <= K; k++)
                    dp[i][j] = min(dp[i][j], dp[i ^ (1 << j)][k] + Cost[k][j]);

    int ans = INF;

    for(int i = 1; i <= K; i++)
        ans = min(ans, dp[(1 << (K + 1)) - 1][i] + Cost[i][K + 1]);

    g << ans;
    return 0;
}