Cod sursa(job #2149615)

Utilizator tanasaradutanasaradu tanasaradu Data 2 martie 2018 19:44:26
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.68 kb
#include <bits/stdc++.h>

using namespace std;
ifstream fin ("ubuntzei.in");
ofstream fout ("ubuntzei.out");
const short Nmax = 2005;
const short Kmax = 17;
const int inf = (1 << 30);
struct Graf
{
    int nod, cost;
    bool operator < (const Graf & e) const
    {
        return cost > e . cost;
    }
};
priority_queue < Graf > Q;
vector < pair < int, int > > L[Nmax];
int dist[Kmax][Kmax], n, m, a[Kmax], p , c[Nmax] , vmax , k , dp[Kmax][1 << Kmax];
bitset < Nmax > viz;

inline void Dijkstra(int nod)
{
    Graf w , w1;
    viz . reset();
    for(int i = 1 ; i <= n ; i++)
        c[i] = inf;
    c[nod] = 0;
    w = {nod , c[nod]};
    Q . push(w);
    while(! Q . empty())
    {
        w = Q . top();
        Q . pop();
        if(!viz[w . nod])
        {
            viz[w . nod] = 1;
            for(auto t : L[w . nod])
            {
                if(c[t . first] > c[w . nod] + t . second)
                {
                    c[t . first] = c[w . nod] + t . second;
                    w1 = {t . first , c[t . first]};
                    Q . push(w1);
                }
            }
        }
    }
}
inline void Read()
{
    int x , y , c;
    fin >> n >> m;
    fin >> k;
    for(int i = 1 ; i <= k ; i++)
    {
        fin >> x;
        if(x == 1 || x == n)
            continue;
        a[++p] = x;
    }
    a[0] = 1;
    p++;
    a[p] = n;
    k = p;
    for(int i = 1 ; i <= m ; i++)
    {
        fin >> x >> y >> c;
        L[x] . push_back({y , c});
        L[y] . push_back({x , c});
    }
    vmax = (1 << k) - 1;
}
inline void Init()
{
    for(int i = 0 ; i <= k ; i++)
        for(int j = 0 ; j <= k ; j++)
            dist[i][j] = inf;
    for(int i = 0 ; i <= k ; i++)
        for(int j = 1 ; j <= vmax ; j++)
            dp[i][j] = inf;
}
inline void Build()
{
    for(int i = 0 ; i <= k ; i++)
    {
        Dijkstra(a[i]);
        for(int j = 0 ; j <= k ; j++)
            dist[i][j] = c[a[j]];
    }
}
inline void Solve_DP()
{
    if(k == 0)
    {
        fout << dist[0][k] << "\n";
        return ;
    }
    dp[0][1] = 0;
    for(int i = 1 ; i <= vmax ; i++)
        for(int j = 0 ; j <= k ; j++)
            if((i & (1 << j)) > 0)
                for(int pas = 0 ; pas <= k ; pas++)
                    if((i & (1 << pas)) == 0)
                        dp[pas][i | (1 << pas)] = min(dp[pas][i | (1 << pas)] , dp[j][i] + dist[j][pas]);
    int sol = inf;
    for(int i = 0 ; i <= k ; i++)
        sol = min(sol , dp[i][vmax] + dist[i][k]);
    fout << sol << "\n";
}
int main()
{
    Read();
    Init();
    Build();
    Solve_DP();
    fin.close();
    fout.close();
    return 0;
}