Cod sursa(job #2446362)

Utilizator AlexandruGabrielAliciuc Alexandru AlexandruGabriel Data 8 august 2019 00:32:27
Problema Ubuntzei Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.55 kb
#include <bits/stdc++.h>

using namespace std;

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

const int NMAX = 2002, KMAX = 18, oo = 1000000000;
int n, m, k;
int cost[NMAX], minCost[KMAX][KMAX], dp[1 << KMAX][KMAX];
bool inCoada[NMAX];
vector < pair <int, int> > L[NMAX];
vector <int> V;

struct cmp
{
    bool operator() (int x, int y)
    {
        return cost[x] > cost[y];
    }
};

priority_queue <int, vector <int>, cmp> Q;

void Read()
{
    fin >> n >> m;
    V.push_back(1);

    fin >> k;
    for (int i = 1; i <= k; i++)
    {
        int nod;
        fin >> nod;
        V.push_back(nod);
    }
    V.push_back(n);

    for (int i = 1; i <= m; i++)
    {
        int a, b, c;
        fin >> a >> b >> c;
        L[a].push_back(make_pair(b, c));
        L[b].push_back(make_pair(a, c));
    }
}

void Dijkstra(int nod_start)
{
    for (int i = 1; i <= n; i++)
    {
        inCoada[i] = 0;
        cost[i] = oo;
    }


    Q.push(nod_start);
    inCoada[nod_start] = 1;
    cost[nod_start] = 0;

    while (!Q.empty())
    {
        int nod_curr = Q.top();
        Q.pop();
        inCoada[nod_curr] = 0;

        for (unsigned int i = 0; i < L[nod_curr].size(); i++)
        {
            int vecin = L[nod_curr][i].first;
            int lungime = L[nod_curr][i].second;

            if (cost[vecin] > cost[nod_curr] + lungime)
            {
                cost[vecin] = cost[nod_curr] + lungime;
                if (!inCoada[vecin])
                {
                    Q.push(vecin);
                    inCoada[vecin] = 1;
                }
            }
        }
    }

}

void findPath()
{
    for (unsigned int i = 0; i < V.size() - 1; i++)
    {
        Dijkstra(V[i]);
        for (unsigned int j = i + 1; j < V.size(); j++)
            minCost[i][j] = minCost[j][i] = cost[V[j]];

    }
}

void calcDp()
{
    int nr_noduri = k + 2;
    for (int i = 0; i < (1 << nr_noduri); i++)
        for (int j = 0; j < nr_noduri; j++)
            dp[i][j] = oo;

    dp[1][0] = 0;
    for (int mask = 1; mask < (1 << nr_noduri); mask += 2)
    {
        for (int i = 0; i < nr_noduri; i++)
            if (mask & (1 << i))
                for (int j = 0; j < nr_noduri; j++)
                    if (i != j && (mask & (1 << j)))
                        dp[mask][i] = min(dp[mask][i], dp[mask ^ (1 << i)][j] + minCost[j][i]);
    }

    fout << dp[(1 << nr_noduri) - 1][nr_noduri - 1];

}

int main()
{
    Read();
    findPath();
    calcDp();
    return 0;
}