Cod sursa(job #2578842)

Utilizator maramihaliMara Mihali maramihali Data 11 martie 2020 17:14:06
Problema Ubuntzei Scor 75
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.41 kb
#include <bits/stdc++.h>

using namespace std;

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

const int maxx = 17;
const int MAX = 2001;
const int INF = 0x7f7f7f7f;

int n, m, k, x, y, z;
int c[maxx], dp[1 << maxx][maxx], cost[MAX], d[MAX][MAX];
char v[MAX];
vector < pair <int, int> > a[MAX];
priority_queue < pair <int, int> > q;

void dijkstra(int start)
{
    for(int i = 1; i <= n; i++)
    {
        v[i] = 0;
        cost[i] = INF;
    }
    cost[start] = 0;
    while (!q.empty())
    {
        q.pop();
    }
    q.push({0, start});
    while(!q.empty())
    {
        while(!q.empty() && v[q.top().second])
        {
            q.pop();
        }
        if(q.empty())
        {
            continue;
        }
        int x = q.top().second;
        q.pop();
        v[x] = 1;
        for(int i = 0; i < a[x].size(); i++)
        {
            int A = a[x][i].first;
            int B = a[x][i].second + cost[x];
            if(B < cost[A])
            {
                cost[A] = B;
                q.push({-cost[A], A});
            }
        }
    }
    for(int i = 1; i <= n; i++)
    {
        d[start][i] = min(d[start][i], cost[i]);
        d[i][start] = min(d[i][start], cost[i]);
    }
}

int main()
{
    in >> n >> m >> k;
    k += 2;
    c[0] = 1;
    c[k - 1] = n;
    for(int i = 1; i < k - 1; i++)
    {
        in >> c[i];
    }
    for(int i = 1; i <= m; i++)
    {
        in >> x >> y >> z;
        a[x].push_back(make_pair(y, z));
        a[y].push_back(make_pair(x, z));
    }
    for(int i = 1; i <= n; i++)
    {
        for(int j = 1; j <= n; j++)
        {
            d[i][j] = INF;
        }
    }
    for(int i = 1; i <= k; i++)
    {
        dijkstra(c[i]);
    }
    for(int i = 0; i < (1 << k); i++)
    {
        for(int j = 0; j < k; j++)
        {
            dp[i][j] = INF;
        }
    }
    dp[1][0] = 0;
    for(int i = 1; i < (1 << k); i++)
    {
        for(int j = 0; j < k; j++)
        {
            if((1 << j)&i)
            {
                for(int t = 0; t < k; t++)
                {
                    if(((1 << t)&i) && j != t)
                    {
                        dp[i][j] = min(dp[i][j], dp[i - (1 << j)][t] + d[c[t]][c[j]]);
                    }
                }
            }
        }
    }
    int L = dp[(1 << k) - 1][k - 1];
    out << L;
    return 0;
}