Cod sursa(job #2389108)

Utilizator Mihai145Oprea Mihai Adrian Mihai145 Data 26 martie 2019 20:19:32
Problema Ubuntzei Scor 55
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.57 kb
#include <fstream>
#include <vector>
#include <queue>

using namespace std;

ifstream fin("ubuntzei.in");
ofstream fout("ubuntzei.out");

const int NMAX = 2000;
const int KMAX = 15;
const int MAXCONFIG = (1 << KMAX);
const int INF = 1000000005;

struct dijkState
{
    int node;
    long long cost;

    bool operator < (const dijkState other) const
    {
        return cost > other.cost;
    }
};

int N, M, K;
int cityes[KMAX + 5], nrord[NMAX + 5];
bool chosen[NMAX + 5];

vector < pair<int, int> > g[NMAX + 5];

int cost[KMAX + 5][KMAX + 5];
int dp[MAXCONFIG][NMAX + 5];

int dist[NMAX + 5];
priority_queue <dijkState> pq;

void Read()
{
    fin >> N >> M >> K;

    cityes[1] = 1;
    chosen[1] = 1;
    for(int i = 1; i <= K; i++)
        fin >> cityes[i], chosen[cityes[i]] = 1;
    cityes[K + 2] = N;
    chosen[N] = 1;

    int f = -1;
    for(int i = 1; i <= N; i++)
        if(chosen[i])
            nrord[i] = ++f;

    int x, y, c;
    for(int i = 1; i <= M; i++)
    {
        fin >> x >> y >> c;
        g[x].push_back({y, c});
        g[y].push_back({x, c});
    }
}

void Dijkstra(int source)
{
    for(int i = 1; i <= N; i++)
    {
        dist[i] = INF;
    }

    pq.push({source, 0});

    while(!pq.empty())
    {
        dijkState state = pq.top();
        pq.pop();

        if(dist[state.node] != INF)
            continue;

        dist[state.node] = state.cost;
        if(chosen[state.node])
            cost[nrord[source]][nrord[state.node]] = cost[nrord[state.node]][nrord[source]] = dist[state.node];

        for(auto it : g[state.node])
            if(dist[it.first] == INF)
                pq.push({it.first, state.cost + it.second});
    }
}

void InitCosts()
{
    K += 2;

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

    for(int i = 1; i <= K; i++)
        Dijkstra(cityes[i]);
}

void SolveHamilton()
{
    for(int config = 0; config < (1 << K); config++)
        for(int f = 0; f < K; f++)
            dp[config][f] = INF;

    dp[1][0] = 0;

    for(int config = 1; config < (1 << K); config++)
        for(int f = 0; f < K; f++)
            if((config & (1 << f)) != 0)
                for(int v = 0; v < K; v++)
                    if(v != f && (config & (1 << v)) != 0)
                        dp[config][f] = min(dp[config][f], dp[config ^ (1 << f)][v] + cost[v][f]);

    fout << dp[(1 << K) - 1][K - 1] << '\n';
}

int main()
{
    Read();

    InitCosts();

    SolveHamilton();

    return 0;
}