Cod sursa(job #3200536)

Utilizator Robert_NicuNicu Robert Cristian Robert_Nicu Data 4 februarie 2024 22:52:07
Problema Ubuntzei Scor 20
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.05 kb
#include <bits/stdc++.h>
#define INF 2*(1e9)
#define DIM 2001
using namespace std;

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


int n, m, k, a, b, c, vecin, cost_vecin, ans, nr;
int drum[17][DIM], dp[17][DIM*17], prieten[17];
int i, j, mask;
vector <pair <int,int>> G[DIM];
set <pair <int,int>> s;

void dijkstra(int nod,int pos){
    for (int i=1; i<=n; i++)
        drum[pos][i]=INF;
    drum[pos][nod]=0;
    s.insert(make_pair(0, nod));
    while(!s.empty()){
        nod=s.begin()->second;
        s.erase(s.begin());
        for(int i=0; i<G[nod].size(); i++){
            vecin=G[nod][i].first;
            cost_vecin=G[nod][i].second;
            if (drum[pos][vecin]>drum[pos][nod]+cost_vecin){
                s.erase(make_pair(drum[pos][vecin], vecin));
                drum[pos][vecin]=drum[pos][nod]+cost_vecin;
                s.insert(make_pair(drum[pos][vecin], vecin));
            }
        }
    }
}
int main(){
    fin>>n>>m>>k;
    for(i=1; i<=k; i++)
        fin>>prieten[i];
    for(i=1; i<=m; i++){
        fin>>a>>b>>c;
        G[a].push_back(make_pair(b,c));
        G[b].push_back(make_pair(a,c));
    }
    for(mask=1; mask<=(1<<k)-1; mask++){
        for(i=1; i<=k; i++)
            dp[i][mask]=INF;
    }
    for(i=1; i<=k; i++)
        dijkstra(prieten[i], i);
    dijkstra(1, 0);
    if(k==0){
        fout<<drum[0][n];
        return 0;
    }
    for(i=1; i<=k; i++)
        dp[(1<<(i-1))][i]=drum[0][prieten[i]];
    for(mask=1; mask<=(1<<k)-1; mask++){
        for(i=1; i<=k; i++){
            if (((mask>>(i-1))&1)==0||mask-(1<<(i-1))==0)
                continue;
            for (j=1; j<=k; j++){
                if (j==i||((mask>>(j-1))&1)==0)
                    continue;
                nr=mask-(1<<(i-1));
                dp[mask][i]=min(dp[mask][i],dp[nr][j]+drum[j][prieten[i]]);
            }
        }
    }
    ans=INF;
    for(i=1; i<=k; i++){
        if(ans>dp[(1<<k)-1][i]+drum[i][n])
            ans=dp[(1<<k)-1][i]+drum[i][n];
    }
    fout<<ans;
}