Cod sursa(job #2984325)

Utilizator AztecaVlad Tutunaru 2 Azteca Data 23 februarie 2023 22:23:59
Problema Ubuntzei Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.43 kb
#include <fstream>
#include <vector>
#include <queue>

using namespace std;

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

const int N=2000+7;
const int INF=(int)1e9;

int n;
int m;

int k;

bool take[N];

struct road
{
        int nod;
        int cost;
};

vector<road>g[N];

int id[N];

int nodes[20];

struct kek
{
        int nod;
        int cost;
};

bool operator < (kek a,kek b)
{
        if(a.cost==b.cost)
        {
                return a.nod<b.nod;
        }
        return a.cost>b.cost;
}

int best[N];

int kr[20][20];

void build(int go)
{
        priority_queue<kek>q;
        q.push({go,0});
        for(int i=1;i<=n;i++)
        {
                best[i]=INF;
        }
        best[go]=0;
        while(!q.empty())
        {
                int nod=q.top().nod;
                int cost=q.top().cost;
                q.pop();
                if(cost!=best[nod]) continue;
                for(auto &it:g[nod])
                {
                        int nou=it.nod;
                        int add=it.cost;
                        int bs=add+cost;
                        if(bs<best[nou])
                        {
                                best[nou]=bs;
                                q.push({nou,bs});
                        }
                }
        }
        for(int i=1;i<=n;i++)
        {
                if(take[i])
                {
                        kr[id[go]][id[i]]=best[i];
                }
        }
}

int dp[(1<<17)][17];

int bits[20],y;

int main()
{
        cin>>n>>m>>k;
        take[1]=take[n]=1;
        for(int i=1;i<=k;i++)
        {
                int nod;
                cin>>nod;
                take[nod]=1;
        }
        int cur=1;
        for(int i=1;i<=n;i++)
        {
                if(take[i])
                {
                        id[i]=cur;
                        nodes[cur]=i;
                        cur++;
                }
        }
        for(int i=1;i<=m;i++)
        {
                int a,b,c;
                cin>>a>>b>>c;
                g[a].push_back({b,c});
                g[b].push_back({a,c});
        }
        for(int i=1;i<=n;i++)
        {
                if(take[i])
                {
                        build(i);
                }
        }
        cur--;
        int tot=(1<<cur);
        for(int a=0;a<(1<<17);a++)
        {
                for(int b=0;b<17;b++)
                {
                        dp[a][b]=INF;
                }
        }
        dp[1][0]=0;
        for(int mask=0;mask<tot;mask++)
        {
                y=0;
                for(int k=0;(1<<k)<=mask;k++)
                {
                        if(mask&(1<<k))
                        {
                                bits[++y]=k;
                        }
                }
                for(int fr=1;fr<=y;fr++)
                {
                        int bt=bits[fr];
                        /// dp[mask][bt]
                        for(int lo=1;lo<=y;lo++)
                        {
                                if(lo==fr) continue;
                                int fk=bits[lo];
                                dp[mask][bt]=min(dp[mask][bt],dp[mask-(1<<bt)][fk]+kr[fk+1][bt+1]);
                        }
                }
        }
        int res=dp[tot-1][cur-1];
        cout<<res<<"\n";
        return 0;
}
/**

**/