Cod sursa(job #3200477)

Utilizator and_Turcu Andrei and_ Data 4 februarie 2024 20:14:05
Problema Ubuntzei Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.75 kb
#include <bits/stdc++.h>
#define N 2007
using namespace std;

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

int n,k,m;
int distanta[N][N];
vector<pair<int,int>>g[N];
vector<int>oras;
int dp[1<<16][16];
/// 17

void Citire()
{
    fin >> n >> m >> k ;
    oras.push_back(1);
    for(int i=1;i<=k;i++)
    {
        int x;
        fin >> x;
        oras.push_back(x);
    }
    k++;
    for(int i=1;i<=m;++i)
    {
        int x,y,c;
        fin >> x >> y >> c;
        g[x].push_back({c,y});
        g[y].push_back({c,x});
    }
    fin.close();
}

void Generare(int poz)
{
    vector<int> viz(N,0);
    priority_queue<pair<int,int> > pq;
    pq.push( {0,oras[poz]} );
    distanta[poz][oras[poz]]=0;
    while( !pq.empty() )
    {
        int cur=pq.top().second;
        pq.pop();
        if( !viz[cur] )
        {
            viz[cur]=1;
            for(auto w: g[cur])
            {
                int nod=w.second;
                int cost=w.first;
                ///                -1
                if( distanta[poz][nod]==0 or distanta[poz][nod]>distanta[poz][cur]+cost )
                {
                    distanta[poz][nod]= distanta[poz][cur]+cost;
                    pq.push( {-distanta[poz][nod],nod} );
                }
            }
        }
    }
}

void Generare_Distante()
{
    for(int i=0;i<k;i++)
        Generare(i);
}

int main()
{
    Citire();
    Generare_Distante();
    if( k==1 )
    {
        fout << distanta[0][n];
        return 0;

    }

    /// distanta de la un nod la el insusi e generata gresit
    int max_mask= (1<<k);
    /// 1 fixat
    for(int i=0;i<max_mask;i++)
        for(int j=0;j<k;j++)
            dp[i][j]=-1;
    dp[1][0]=0;
    for(int mask=3;mask<max_mask;mask+=2)
    {
        for(int i=0;i<k;i++)
            if( mask&(1<<i) )
            {
                int new_mask=mask-(1<<i);
                for(int j=0;j<k;j++)
                    if( new_mask&(1<<j) )
                    {
                        if( dp[new_mask][j]!=-1
and ( dp[mask][i]>dp[new_mask][j]+distanta[ j ][ oras[i] ] or dp[mask][i]==-1 ) )
                        {
                            dp[ mask ][ i ]= dp[new_mask][j]+distanta[ j ][ oras[i] ];
                        }
                    }
            }
    }
//    for(int i=0;i<k;i++)
//        cout << setw(3) << i ;
//    cout << "\n";
//    for(int mask=1;mask<max_mask;mask+=2,cout <<"\n")
//    {
//        cout << mask <<":  \n";
//        for(int i=0;i<k;i++)
//            cout << setw(3) <<  dp[mask][i] ;
//    }



    int sol=-1;
    for(int i=1;i<k;i++)
    {
        if( dp[ max_mask-1 ][ i ]+distanta[ i ][ n ]!=-1 and ( sol==-1 or dp[ max_mask-1 ][ i ]+distanta[ i ][ n ]<sol )  )
            sol=dp[ max_mask-1 ][ i ]+distanta[ i ][ n ];
    }
    fout << sol <<"\n";
    return 0;
}