Cod sursa(job #2500557)

Utilizator FrostfireMagirescu Tudor Frostfire Data 28 noiembrie 2019 10:35:18
Problema Ubuntzei Scor 20
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.48 kb
#include <fstream>
#include <iostream>
#include <vector>
#include <queue>
#include <cstring>
#define NMAX 2000
#define inf 2000000000000

using namespace std;

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

long long sol, nr, n, k, m, v[20], di[NMAX+10], dist[20][20], dp[(1<<16)+100][16];
bool b[NMAX+10];
vector <pair <long long, long long> > nod[NMAX+10];
priority_queue <pair <long long, long long>, vector <pair <long long, long long> >, greater <pair <long long, long long> > > pq;

void dijkstra(int x)
{   memset(b, 0, sizeof(b));
    memset(di, 0, sizeof(di));
    for(int i=1; i<=n; i++) di[i] = inf;
    while(!pq.empty()) pq.pop();
    pq.push(make_pair(0, v[x]));
    while(!pq.empty())
        {   pair <int, int> a = pq.top();
            pq.pop();
            if(!b[a.second])
                {   b[a.second] = 1;
                    for(int i=0; i<nod[a.second].size(); i++)
                        {   int d = a.first + nod[a.second][i].first;
                            if(d < di[nod[a.second][i].second])
                                {   di[nod[a.second][i].second] = d;
                                    pq.push(make_pair(d, nod[a.second][i].second));
                                }
                        }
                }
        }
    for(int i=0; i<=k; i++) dist[x][i] = di[v[i]];
    dist[x][x] = 0;
}

int main()
{
    f >> n >> m >> k;
    for(int i=1; i<=k; i++) f >> v[i];
    v[0] = 1;
    v[++k] = n;
    for(int i=1; i<=m; i++)
        {   int nod1, nod2, cost;
            f >> nod1 >> nod2 >> cost;
            nod[nod1].push_back(make_pair(cost, nod2));
            nod[nod2].push_back(make_pair(cost, nod1));
        }
    for(int i=0; i<=k; i++) dijkstra(i);
    if(k == 1)
        {   g << dist[0][1] << '\n';
            return 0;
        }

    for(int mask=1; mask<(1<<(k-1)); mask++)
        for(int i=0; i<k-1; i++) dp[mask][i] = inf;
    for(int mask=1; mask<(1<<(k-1)); mask*=2) dp[mask][nr++] = dist[0][nr+1];

    for(int mask=1; mask<(1<<(k-1)); mask++)
        if((mask & (mask-1)))
            for(int i=0; i<k-1; i++)
                if(mask & (1 << i))
                    for(int j=0; j<k-1; j++)
                        if(i != j && (mask & (1 << j)))
                            dp[mask][i] = min(dp[mask][i], dp[mask^(1<<i)][j] + dist[i+1][j+1]);

    sol = inf;
    for(int i=0; i<k-1; i++) sol = min(sol, dp[(1<<(k-1))-1][i] + dist[i+1][k]);
    g << sol << '\n';
    return 0;
}