Cod sursa(job #2282002)

Utilizator moise_alexandruMoise Alexandru moise_alexandru Data 13 noiembrie 2018 01:10:56
Problema Ubuntzei Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.23 kb
#include <algorithm>
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
using namespace std;
ifstream in("ubuntzei.in");
ofstream out("ubuntzei.out");
const int maxn = 2005;
vector <pair <int, int> > v[maxn];
int dp[18][(1 << 17) + 20];
int drum[maxn][maxn];
int ubuntel[maxn];
int n;

class cmp
{
public:
    bool operator()( pair<int, int> a, pair<int, int> b )
    {
        return a.second > b.second;
    }
};
priority_queue<pair<int, int>, vector< pair<int, int> >, cmp> pq;

void drum_min(int x)
{
    drum[ubuntel[x]][x] = 0;
    pq.push(make_pair(ubuntel[x], 0));
    while(!pq.empty())
    {
        pair<int, int> p = pq.top();
        pq.pop();
        /*
        if(p.second > drum[p.first])
            continue;
        */
        if(p.second == drum[p.first][x])
        {
            for(auto it : v[p.first])
            {
                if(drum[it.first][x] > it.second + p.second)
                {
                    drum[it.first][x] = it.second + p.second;
                    pq.push(make_pair(it.first, it.second + p.second));
                }
            }
        }
    }
}

int main()
{
    int m, k;
    in >> n >> m >> k;
    ubuntel[1] = 1;
    k++;
    for(int i = 2; i <= k; i++)
        in >> ubuntel[i];
    ubuntel[++k] = n;
    for(int i = 1; i <= m; i++)
    {
        int x, y, z;
        in >> x >> y >> z;
        v[x].push_back(make_pair(y, z));
        v[y].push_back(make_pair(x, z));
    }
    for(int i = 1; i <= n; i++)
        for(int j = 0; j <= k; j++)
            drum[i][j] = (1 << 30);
    for(int i = 0; i <= k; i++)
        for(int j = 0; j <= (1 << k); j++)
            dp[i][j] = (1 << 30);
    dp[1][1] = 0;
    for(int i = 1; i <= k; i++)
        drum_min(i);
    for(int conf = 0; conf < (1 << k); conf++)
    {
        for(int i = 0; i < k; i++)
        {
            if(conf & (1 << i))
                continue;
            for(int j = 0; j < k; j++)
                if(i != j && (conf & (1 << j)))
                    dp[i + 1][conf + (1 << i)] = min(dp[i + 1][conf + (1 << i)], dp[j + 1][conf] + drum[ubuntel[i + 1]][j + 1]);
        }
    }
    out << dp[k][(1 << k) - 1] << "\n";
    return 0;
}