Cod sursa(job #2162382)

Utilizator Y0da1NUME JMECHER Y0da1 Data 12 martie 2018 10:33:58
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.39 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <bitset>

using namespace std;
const int oo = 2e9;
const int maxn = 2018;
int N, M, K;
int opriri[20];
int dist[2018][2018];
int dp[(1<<20)][20];

bitset <maxn> viz;
vector <pair <int, int> > G[maxn];
priority_queue <pair <int, int>,
                vector<pair <int, int> >,
                greater <pair <int, int> > > heap;
int main()
{
    ifstream in ("ubuntzei.in");
    ofstream out ("ubuntzei.out");
    in>>N>>M>>K;
    for(int i = 1; i <= K; ++i)
        in>>opriri[i];
    opriri[0] = 1;
    opriri[K + 1] = N;
    for(int i = 1; i <= M; ++i)
    {
        int x, y, z;
        in>>x>>y>>z;
        G[x].push_back(make_pair(y, z));
        G[y].push_back(make_pair(x, z));
    }

    for(int i = 0; i <= K; ++i)
    {
        viz.reset();
        for(int j = 1; j <= N; ++j)
            dist[opriri[i]][j] = oo;
        dist[opriri[i]][opriri[i]] = 0;
        heap.push(make_pair(0, opriri[i]));
        while(!heap.empty())
        {
            int nod = heap.top().second;
            int d = heap.top().first;
            heap.pop();
            if(viz[nod])
                continue;
            viz[nod] = 1;
            for(int k = 0; k < G[nod].size(); ++k)
                if(dist[opriri[i]][G[nod][k].first] > d + G[nod][k].second)
                {
                    dist[opriri[i]][G[nod][k].first] = d + G[nod][k].second;
                    heap.push(make_pair(d + G[nod][k].second, G[nod][k].first));
                }
        }
    }

    if (K == 0)
    {
        out << dist[1][N];
        return 0;
    }
    //cout<<oo;
    for(int i = 0; i < (1<<(K+1)); ++i)
        for(int j = 0; j <= K; ++j)
            dp[i][j] = oo;
    dp[1][0] = 0;
    //urmeaza ciclu hamiltonian
    for(int conf = 0; conf < (1<<(K + 1)); ++conf)
        for(int i = 0; i <= K; ++i)
            if(conf & (1<<i))
                for (int j = 0; j <= K; ++j)
                    if (j != i && (conf & (1<<j)))
                        dp[conf][i] = min (dp[conf][i], dp[conf ^ (1<<i)][j] + dist[opriri[j]][opriri[i]]);

    int sol = oo;
    for (int i = 0; i <= K; ++i)
    {
            //cout<<i<<" "<< dp[(1<<(K + 1)) - 1][i] + dist[opriri[i]][N];
            sol = min(sol, dp[(1<<(K + 1)) - 1][i] + dist[opriri[i]][N]);
    }

    out<<sol;

    return 0;
}