Cod sursa(job #2553713)

Utilizator Rares31100Popa Rares Rares31100 Data 22 februarie 2020 11:18:12
Problema Ubuntzei Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.08 kb
#include <bits/stdc++.h>
#define Inf 100000007
#define PII pair<int,int>
#define Nod second
#define Dist first

using namespace std;

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

int n,m,k;
int vf[20001],urm[20001],cost[20001],last[2001],nr;
int dp[17][(1<<17)];
int loc[18],distL[17][17];

priority_queue <PII,vector<PII>,greater<PII>> c;
bitset <2001> viz;
int dist[2001];

void adauga(int nod,int vec,int ct)
{
    vf[++nr]=vec;
    urm[nr]=last[nod];
    last[nod]=nr;
    cost[nr]=ct;
}

void djikstra(int start,int r)
{
    for(int i=1;i<=n;i++)
    {
        dist[i]=Inf;
        viz[i]=0;
    }
    
    dist[start]=0;
    c.push({0,start});
    
    while( !c.empty() )
    {
        while( !c.empty() && viz[ c.top().Nod ] )
            c.pop();
            
        if( c.empty() )
            break;
            
        int nod=c.top().Nod;
        int dNod=c.top().Dist;
        viz[nod]=1;
        
        for(int k=last[nod];k;k=urm[k])
            if(!viz[ vf[k] ] && cost[k]+dNod<dist[ vf[k] ])
            {
                dist[ vf[k] ]=cost[k]+dNod;
                c.push({dist[ vf[k] ], vf[k]});
            }
    }
    
    for(int i=1;i<=k;i++)
        distL[r-1][i-1]=dist[ loc[i] ];
}

int main()
{
    in>>n>>m>>k;
    
    for(int i=1;i<=k;i++)
        in>>loc[i+1];
    loc[1]=1;
    loc[k+2]=n;
    k+=2;
    
    for(int i,j,ct,q=1;q<=m;q++)
    {
        in>>i>>j>>ct;
        
        adauga(i,j,ct);
        adauga(j,i,ct);
    }
    
    for(int i=1;i<=k;i++)
        djikstra(loc[i], i);
    
    for(int i=0;i<(1<<k);i++)
        for(int nod=0;nod<k;nod++)
            dp[nod][i]=Inf;
    
    for(int i=0;i<k;i++)
        dp[i][(1<<i)]=distL[0][i];
    
    for(int i=1;i<(1<<k);i++)    
        for(int nod=0;nod<k;nod++)
            if(i&(1<<nod))
                for(int j=0;j<k;j++)
                    if(i&(1<<j))
                        dp[nod][i]=min(dp[nod][i], dp[j][i-(1<<nod)]+distL[j][nod]);
                    
    int minim=Inf;
    
    for(int i=0;i<k;i++)
        minim=min(minim, dp[i][(1<<k)-1]+distL[i][k-1]);
        
    out<<minim;
    
    return 0;
}