Cod sursa(job #2034420)

Utilizator raulrusu99Raul Rusu raulrusu99 Data 7 octombrie 2017 19:45:41
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.56 kb
#include <iostream>
#include <fstream>
#include <queue>
#include <vector>
#define N_MAX 2005
#define inf (1<<31)-1
using namespace std;
ifstream f("ubuntzei.in");
ofstream g("ubuntzei.out");
///                   dist/nod
priority_queue <pair <int, int> > pq;
///           nod  dist
vector <pair <int, int> > G[N_MAX];
int dist[N_MAX][N_MAX], n, m, k;
int ub[20];
int dp[140072][17];

void dijkstra(int start)
{
    bool viz[N_MAX] = {0};
    pair <int, int> _top;
    int nod;
    pq.push(make_pair(0, start));
    dist[start][start] = 0;
    while(!pq.empty())
    {
        _top = pq.top();
        pq.pop();
        nod = _top.second;
        if(viz[nod])
            continue;
        viz[nod] = 1;
        for(auto it:G[nod])
        {
            if(it.second + dist[start][nod] < dist[start][it.first])
            {
                dist[start][it.first] = it.second + dist[start][nod];
                pq.push(make_pair(-dist[start][it.first], it.first));
            }
        }
    }
}

int main()
{
    f >> n >> m >> k;
    for(int i = 0 ; i < k ; i++)
        f >> ub[i];
    ub[k] = n;
    int x, y, z;
    for(int i = 1; i <= m; i++)
    {
        f >> x >> y >> z;
        G[x].push_back(make_pair(y, z));
        G[y].push_back(make_pair(x, z));
    }

    for(int i = 0; i <= n; i++)
        for(int j = 0; j<= n; j++)
            dist[i][j] = inf;
    dijkstra(1);
    for(int i = 0; i < k; i++)
        dijkstra(ub[i]);
    dijkstra(n);

    int ii;

    for(int i = 0; i <= (1<<(k+1)) - 1; i++)
        for(int j = 0; j < k + 1; j++)
        dp[i][j] = inf;

    for(int j = 0; j < k + 1; j++)
    {
        dp[(1 << j)][j] = dist[1][ub[j]];
    }

    for(int i = 1; i <= (1<<(k+1)) - 1; i++)
    {
        for(int j = 0; j < k + 1; j++)
        {
            ii = i & ~(1 << j);
            if(i != ii)
            {
                for(int jj = 0; jj < k+1; jj++)
                {
                    dp[i][j] = min(1LL * dp[i][j], 1LL * dp[ii][jj] + dist[ub[jj]][ub[j]]);
                }
            }
        }
    }
//    cout << "\n";
//     for(int i = 1; i <= (1<<(k+1)) - 1; i++)
//     {
//         for(int j = 0; j < k + 1; j++)
//            cout << dp[i][j] << " ";
//        cout << "\n";
//     }
    long long rez = inf;
    for(int j = 0; j < k; j++)
    {
        rez = min(rez, 1LL * dp[(1<<(k+1))-1][j] + dist[ub[j]][n]);
        //cout << dp[(1<<(k+1)) - 1][j] + dist[ub[j]][n] << " ";
    }
    rez = min(rez,1LL *  dp[(1<<(k+1))-1][k]);
    g << rez;
    return 0;
}