Cod sursa(job #2560903)

Utilizator AndreiDeltaBalanici Andrei Daniel AndreiDelta Data 28 februarie 2020 12:49:36
Problema Ubuntzei Scor 65
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.89 kb
#include <bits/stdc++.h>
#define Dim 2020
#define Lim (1<<20)+10
#define oo 1e9+1
using namespace std;
ifstream f("ubuntzei.in");
ofstream g("ubuntzei.out");
int N,M,K,a,b,c,dp[Lim][20],ans=-1,Poz[Dim],ras,Frd[20],How[20],C[Dim][Dim];

struct edge
{
    int ver,pay;
};

vector < edge > V[Dim];


void Bell(int P)
{
    set < int > S;

    C[P][P]=0;
    S.insert(P);

    while(!S.empty())
    {
        int nod=*S.begin();
        S.erase(S.begin());

        for(unsigned int i=0;i<V[nod].size();i++)
        {
            int vecin=V[nod][i].ver;
            int cost=V[nod][i].pay;

            if( C[P][nod] + cost < C[P][vecin] )
            {
                if( S.find(vecin) != S.end() ) S.erase(S.find(vecin));
                C[P][vecin]=C[P][nod]+cost;
                S.insert(vecin);
            }
        }
    }
}

int main()
{
    f>>N>>M>>K;
    Poz[1]=0;
    Frd[1]=1;
    How[0]=1;
    for(int i=1;i<=K;i++)
    {
        f>>a;
        Poz[a]=i;
        How[i]=a;
        Frd[i+1]=a;
    }
    K++;
    Poz[N]=K;
    How[K]=N;
    Frd[K+1]=N;

    for(int i=1;i<=M;i++)
    {
        f>>a>>b>>c;
        V[a].push_back({b,c});
        V[b].push_back({a,c});
    }

    for(int i=1;i<=N;i++)
    for(int j=1;j<=N;j++) C[i][j]=oo;

    for(int i=1;i<=K+1;i++)
    Bell(Frd[i]);

    for(int i=1;i<(1<<(K+1));i++)
    for(int j=0;j<=K;j++) dp[i][j]=oo;

    dp[1][0]=0;
    for(int i=2;i<( 1 << ( K + 1 ) );i++)
    for(int j=0;j<=K;j++)
    if( ( i & ( 1 << j ) ) > 0 )
    {
        for(int q=0;q<=log2(i)+1;q++)
        {
            if( q!=j && ( ( i & (1<<q) ) > 0 ) )
        {

            dp[i][j]=min(dp[i][j],dp[ i ^ ( 1<< j ) ][q] + C[How[j]][How[q]]);
           // cout<<i<<' '<<j<<' '<<q<<' '<<C[How[j]][How[q]]<<' '<<dp[i][j]<<'\n';
        }
        }

    }
    g<<dp[(1<<(K+1))-1][K];

    return 0;
}