Cod sursa(job #2374699)

Utilizator crion1999Anitei cristi crion1999 Data 7 martie 2019 20:01:27
Problema Ubuntzei Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.21 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>

#define NMAX 20000
#define KMAX 20
#define inf 0x3f3f3f3f

using namespace std;

ifstream fi("ubuntzei.in");
ofstream fo("ubuntzei.out");


struct Edge{
    int node;
    int cost;

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

    Edge(int aNode, int aCost)
    {
        node = aNode;
        cost = aCost;
    }
};

int N, M, K;

int friends[KMAX];

int dp[KMAX][(1 << KMAX)];

int cost[NMAX][NMAX];

vector<Edge> graph[NMAX];


void DoADjikstraFlip(int origin)
{
    priority_queue<Edge> q;
    q.push({origin, 0});

    for(int i = 1; i <= N; ++i)
        cost[origin][i] = inf;

    cost[origin][origin] = 0;

    while(!q.empty())
    {
        Edge top = q.top();
        q.pop();

        if(cost[origin][top.node] != top.cost)
            continue;

        for(auto y: graph[top.node])
        {
            if(cost[origin][y.node] > top.cost + y.cost)
            {
                cost[origin][y.node] = top.cost + y.cost;
                q.push({y.node, cost[origin][y.node]});
            }
        }
    }
}

int main()
{
    fi >> N >> M;
    fi >> K;
    K += 2;
    friends[0] = 1;
    friends[K-1] = N;
    for(int i = 1; i < K-1; ++i)
        fi >> friends[i];

    for(int i = 1; i <= M; ++i)
    {
        int a, b, c;
        fi >> a >> b >> c;
        graph[a].push_back({b, c});
        graph[b].push_back({a, c});
    }

    for(int i = 0; i < K; ++i)
        DoADjikstraFlip(friends[i]);

    if(K-2 == 0)
    {
        fo << cost[1][N];
        return 0;
    }

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

    for(int i = 0; i < K; ++i)
        dp[i][1 << i] = cost[1][friends[i]];

    for(int i = 1; i < (1 << K); ++i)
        for(int j = 0; j < K; ++j)
            if((1 << j) & i)
                for(int z = 0; z < K; ++z)
                    if(!((1 << z) & i))
                        dp[z][i ^ (1 << z)] = min(dp[z][i ^ (1 << z)], dp[j][i] + cost[friends[j]][friends[z]]);

    fo << dp[K-1][(1 << K) - 1];








}