Cod sursa(job #2710192)

Utilizator VladNANegoita Vlad-Andrei VladNA Data 22 februarie 2021 09:06:13
Problema Ubuntzei Scor 20
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.18 kb
#include <bits/stdc++.h>
#define NMAX 2001
#define KMAX 18
#define INF 1e9
using namespace std;

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

vector <pair <int,int> >adj[NMAX];
vector<int>ub;
int d[KMAX][KMAX],ruta[NMAX],distante[NMAX];
int dp[KMAX][1<<KMAX];
int n,m,k;

void dijkstra(int ind)
{
    for(int i=1;i<=n;i++)
        distante[i]=INF;
    priority_queue < pair <int, int> >pq;
    distante[ub[ind]]=0;
    pq.push({0,ub[ind]});
    while(!pq.empty())
    {
        pair<int, int>u=pq.top();
        pq.pop();
        if(ruta[u.second]!=0 || u.second==1)
            d[ind][ruta[u.second]]=distante[u.second];
        for(vector < pair <int, int> >::iterator it=adj[u.second].begin();it!=adj[u.second].end();it++)
        {
            pair <int, int> v=*it;
            if(distante[v.second]>distante[u.second]+v.first)
            {
                distante[v.second]=distante[u.second]+v.first;
                pq.push({-distante[v.second],v.second});
            }
        }
    }

}

int main()
{
    in>>n>>m>>k;
    ub.push_back(1);
    ruta[1]=0;
    for(int i=1;i<=k;i++){
        int nr;
        in>>nr;
        ruta[nr]=i;
        ub.push_back(nr);
    }
    ub.push_back(n);
    ruta[n]=k+1;
    for(int i=1;i<=m;i++)
    {
        int a,b,cost;
        in>>a>>b>>cost;
        adj[a].push_back({cost,b});
        adj[b].push_back({cost,a});
    }
    for(int i=0;i<ub.size();i++)
        for(int j=0;j<ub.size();j++)
            d[i][j]=INF;
    for(int i=0;i<ub.size();i++)
        dijkstra(i);
    int mask_max=(1<<k)-1;
    for(int i=1;i<=k;i++)
        for(int mask=1;mask<=mask_max;mask++)
            dp[i][mask]=INF;
    for(int i=1;i<=k;i++)
        dp[i][1 <<(i-1)]=d[0][i];
    for(int i=1;i<=k;i++)
        for(int j=1;j<=k;j++)
            for(int mask=1;mask<=mask_max;mask++)
                if((mask & (1 << (j-1)))==0)
                    dp[j][mask+(1 << (j-1))]=min(dp[j][mask+ (1 << (j-1) )],dp[i][mask]+d[i][j]);
    int rez=INF;
    for(int i=1;i<=k;i++)
        rez=min(rez,dp[i][mask_max]+d[i][k+1]);
    if(k==0)
        out<<d[0][k+1];
    else
        out<<rez;
    return 0;
}