Cod sursa(job #3345081)

Utilizator Gabriel_DaescuDaescu Gabriel Florin Gabriel_Daescu Data 7 martie 2026 21:19:11
Problema Ubuntzei Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.47 kb
#include <fstream>
#include <queue>
#define NMAX 2009
#define KMAX 15
#define INF 1<<30
using namespace std;
ifstream  fin("ubuntzei.in");
ofstream fout("ubuntzei.out");
int N,M,K,C[KMAX],graph[NMAX][NMAX];
int ds[KMAX],df[KMAX],d[KMAX][KMAX],dp[1<<KMAX][KMAX];

void citire()
{
    fin>>N>>M>>K;

    for(int i=0; i<K; i++)
    {
        fin>>C[i];
        C[i]--;
    }

    int a,b,c;
    for(int i=0; i<M; i++)
    {
        fin>>a>>b>>c;
        a--;
        b--;
        graph[a][b]=graph[b][a]=c;
    }
}

void calculare_distante(int start)
{
    priority_queue<pair<int,int>,vector<pair<int,int>>,greater<pair<int,int>>>pq;
    int dist[NMAX],viz[NMAX];
    for(int i=0; i<N; i++)
    {
        dist[i]=INF;
        viz[i]=0;
    }

    dist[C[start]]=0;
    pq.push({0,C[start]});

    while(!pq.empty())
    {
        int nod=pq.top().second;
        pq.pop();

        if(!viz[nod])
        {
            viz[nod]=1;
            for(int i=0; i<N; i++)
            {
                if(graph[nod][i] && dist[i]>dist[nod]+graph[nod][i])
                {
                    dist[i]=dist[nod]+graph[nod][i];
                    pq.push({dist[i],i});
                }
            }
        }
    }

    ds[start]=dist[0];
    df[start]=dist[N-1];

    for(int i=0; i<K; i++)
    {
        d[start][i]=dist[C[i]];
    }
}

int main()
{
    citire();

    if(!K)
    {
        calculare_distante(0);
        fout<< df[0] << "\n";
        return 0;
    }

    for(int i=0; i<K; i++)
    {
        calculare_distante(i);
    }

    for(int i=0; i<(1<<K); i++)
    {
        for(int j=0; j<K; j++)
        {
            dp[i][j]=INF;
        }
    }

    for(int i=0; i<K; i++)
    {
        dp[1<<i][i]=ds[i];
    }

    for(int i=0; i<(1<<K); i++)
    {
        for(int j=0; j<K; j++)
        {
            if(i&(1<<j))
            {
                for(int k=0; k<K; k++)
                {
                    if(!(i&(1<<k)))
                    {
                        if(dp[i|(1<<k)][k]>dp[i][j]+d[j][k])
                        {
                            dp[i|(1<<k)][k]=dp[i][j]+d[j][k];
                        }
                    }
                }
            }
        }
    }

    int ans=INF;
    for(int i=0; i<K; i++)
    {
        if(dp[(1<<K)-1][i]+df[i]<ans)
        {
            ans=dp[(1<<K)-1][i]+df[i];
        }
    }

    fout<< ans << "\n";

    return 0;
}