Cod sursa(job #2527581)

Utilizator dey44andIoja Andrei-Iosif dey44and Data 20 ianuarie 2020 17:44:47
Problema Ubuntzei Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.52 kb
#include <bits/stdc++.h>

#define input "ubuntzei.in"
#define output "ubuntzei.out"
#define CMAX 20
#define NMAX 2005
#define SMAX 262150
#define inf 1e9

using namespace std;

ifstream in(input);
ofstream out(output);

struct muchie
{
    int y, cost;
};
int N, M, K, cost[CMAX][CMAX], nodes[CMAX], dist[NMAX], dp[SMAX][CMAX];
bool uz[NMAX];
vector < muchie > muchii[NMAX];
queue < int > coada;

void Read_Data()
{
    in >> N >> M >> K;
    nodes[0] = 1;
    for(int i = 1; i <= K; i++)
        in >> nodes[i];
    nodes[K + 1] = N;
    K += 2;
    for(int i = 1; i <= M; i++)
    {
        int x, y, c; in >> x >> y >> c;
        muchii[x].push_back({y, c});
        muchii[y].push_back({x, c});
    }
}

void Bellman_Ford(int nod2)
{
    for(int i = 1; i <= N; i++)
        uz[i] = 0, dist[i] = inf;
    uz[nodes[nod2]] = 1, dist[nodes[nod2]] = 0; coada.push(nodes[nod2]);
    while(!coada.empty())
    {
        int nod = coada.front(); coada.pop(); uz[nod] = 0;
        int dist_nod = dist[nod];
        for(unsigned i = 0; i < muchii[nod].size(); i++)
        {
            int new_nod = muchii[nod][i].y;
            int new_dist = muchii[nod][i].cost;
            if(dist_nod + new_dist < dist[new_nod])
            {
                dist[new_nod] = dist_nod + new_dist;
                if(!uz[new_nod])
                {
                    coada.push(new_nod);
                    uz[new_nod] = 1;
                }
            }
        }
    }
    for(int i = 0; i < K; i++)
        cost[nod2][i] = cost[i][nod2] = dist[nodes[i]];
}

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

void Solve()
{
    for(int i = 0; i < K; i++)
        Bellman_Ford(i);
    for(int i = 0; i < K; i++)
        for(int j = 0; j < K; j++)
            if(cost[i][j] == 0) cost[i][j] = inf;
}

void DP_Exp()
{
    Init();
    dp[1][0] = 0;
    if(K == 2)
    {
        out << cost[0][1] << "\n";
        return;
    }
    int Subs = 1 << K;
    for(int sub = 3; sub < Subs; sub += 2)
        for(int i = 1; i < K; i++)
            if(sub & (1 << i))
                for(int j = 0; j < K; j++)
                    dp[sub][i] = min(dp[sub][i], dp[(sub ^ (1 << i))][j] + cost[j][i]);
    int best_sol = inf;
    best_sol = dp[Subs - 1][K - 1];
    if(best_sol == inf) out << "Nu exista solutie\n";
    else out << best_sol << "\n";
}

int main()
{
    Read_Data();
    Solve();
    DP_Exp();
    return 0;
}