Cod sursa(job #2359692)

Utilizator tiberiu392Tiberiu Ungurianu tiberiu392 Data 1 martie 2019 00:53:49
Problema Ubuntzei Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.12 kb
#include <bits/stdc++.h>
#define limn 2010
#define limk 20
#define inf 2e9

using namespace std;

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

int n,m,k, nod, cost, dp[1<<limk][limk], x,y,c;
vector <pair<int, int> > V[limn];
int ini[limk],  path[limn][limn];
priority_queue <pair <int, int> > q;

int main()
{
    f >> n >> m;
    f >> k;
    for (int i = 1; i <= k ; i++)
        f >> ini[i];
    for (int i = 1; i <= m ; i++)
    {
        f>>x>>y>>c;
        V[x].push_back({y,c});
        V[y].push_back({x,c});
    }

    ini[0]=1;
    for (int i = 0; i <= k ; i++)
    {
        for (int j = 1 ; j <= n; j++)
        path[ini[i]][j]=inf;
        path[ini[i]][ini[i]] = 0;
        q.push({0,ini[i]});
        while (!q.empty())
        {
            nod = q.top().second;
            cost = -q.top().first;
            q.pop();
            if (path[ini[i]][nod] != cost)
                continue;
            for (auto it:V[nod])
                if (path[ini[i]][it.first] > path[ini[i]][nod] + it.second)
                {
                    path[ini[i]][it.first] = path[ini[i]][nod] + it.second;
                    q.push({-path[ini[i]][it.first], it.first});
                }
        }
    }

    if ( k == 0 )
    {
        g << path[1][n];
        return 0;
    }

    for (int i = 1; i <= k ; i++ )
        dp[ 1<<(i-1)][i] = path[1][ini[i]];

    for (int l = 1 ; l < (1<<k); l++ )
        {
            for (int i = 1; i <= k ; i++ )
            if ( l & (1<<(i-1)) )
                {
                    for ( int j = 1 ; j <= k ; j++ )
                    {
                        if ( j != i && (l & (1<<(j-1))) )
                        if ( !dp[l][i] || dp[l][i] > dp[l-(1<<(i-1))][j] + path[ini[j]][ini[i]] )
                            dp[l][i] = dp[l-(1<<(i-1))][j] + path[ini[j]][ini[i]];
                    }
                }
        }

    int minim = inf;
    int l = (1<<k)-1;
    for (int i = 1 ; i <= k ; i++ )
    if ( dp[l][i] && dp[l][i] + path[ini[i]][n] < minim)
    minim = dp[l][i] + path[ini[i]][n];

    g<<minim;
    return 0;
}