Cod sursa(job #2720144)

Utilizator stefan1anubystefan popa stefan1anuby Data 10 martie 2021 17:08:12
Problema Ubuntzei Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.78 kb
#include <fstream>
#include <vector>
#include <queue>

using namespace std;

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

#define NMAX 2005
#define KMAX 18
#define INF 2e9

vector < pair < int, int > > G[NMAX];
priority_queue < pair < int, int > > Q;
int C[NMAX],Cost[KMAX][KMAX],DP[(1<<KMAX) + 5][KMAX];
int N,M,K;

void read()
{
    int i,j,x,y,z;
    cin>>N>>M;
    cin>>K;
    for(i=1; i<=K; i++)
        cin>>C[i];
    for(i=1; i<=M; i++)
    {
        cin>>x>>y>>z;
        G[x].push_back({y,z});
        G[y].push_back({x,z});
    }
}

int d[NMAX+2];
void Dijkstra(int start)
{
    int i;
    for(i=1; i<=N; i++)
        d[i]=INF;
    Q.push({0,start});
    d[start]=0;
    while(Q.empty()==false)
    {
        int node=Q.top().second;
        Q.pop();
        for(auto edge: G[node])
        {
            int next_node=edge.first;
            int next_cost=edge.second;
            if(d[node]+next_cost<d[next_node])
            {
                d[next_node]=d[node]+next_cost;
                Q.push({-d[next_node],next_node});
            }
        }
    }
}

void getCost()
{
    int i,j;
    for(i=1; i<=K; i++)
        for(j=1; j<=K; j++)
            Cost[i][j]=INF;
    for(i=1; i<=K; i++)
    {
        Dijkstra(C[i]);
        for(j=1; j<=K; j++)
            Cost[i][j]=d[C[j]];
    }
    Dijkstra(1);
    /*for(i=1;i<=K;i++)
        Cost[K+1][i]=d[C[i]];*/
}

void afis()
{
    int i,j;
    for(i=1; i<=K; i++)
    {
        for(j=1; j<=K; j++)
            cout<<Cost[i][j]<<" ";
        cout<<endl;
    }
}

/// DP[i][j] : drumul optim care se termina in j avand bitii din i activati
void solve()
{
    int i,j,mask,k;
    read();
    getCost();
    for(i=0; i< (1<<K) ; i++)
        for(j=0; j<=K; j++)
            DP[i][j]=INF;
    for(mask=1; mask < (1<<K); mask++) /// setul de intersectii
    {
        for(j=0; j<K; j++) /// aleg ultima intersectie
        {
            if(mask & (1<<j))
            {
                if(mask-(1<<j)!=0) /// maska are cel putin 2 biti setati
                {
                    for(k=0; k<K; k++) /// aleg penultimul bit
                    {
                        if(j!=k && (mask & (1<<k)) ) /// bitul k e setat pe 1
                        {
                            DP[mask][j]=min(DP[mask-(1<<k)][k]+Cost[k+1][j+1],DP[mask][j]);
                        }
                    }
                }
                else /// maska are 1 bit setat
                {
                    DP[mask][j]=d[C[j+1]];
                }
            }
        }
    }
    Dijkstra(N);
    int sol=INF;
    for(i=0; i<K; i++)
        sol=min(DP[mask-1][i]+d[C[i+1]],sol);
    cout<<sol;
}

int main()
{
    solve();
//  afis();
    return 0;
}