Cod sursa(job #2219994)

Utilizator 12222Fendt 1000 Vario 12222 Data 10 iulie 2018 12:18:30
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.33 kb
#include <bits/stdc++.h>

using namespace std;

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

const int nmax=2002;
const int mmax=10002;
const int pmax=(1<<17)+2;
const int oo=(2e9);

struct Perechi
{
    int nod,cost;
    bool operator <(const Perechi &e) const
    {
        return cost>e.cost;
    }
};

int n,m,k;
int C[18],dist[nmax],dp[pmax][18],cost[18][18];
vector<Perechi>L[mmax];
priority_queue<Perechi>q;

void Citire()
{
    fin>>n>>m;
    fin>>k;

    for(int i=1;i<=k;i++)
        fin>>C[i];
    C[0]=1;
    C[++k]=n;

    int x,y,z;
    for(int i=1;i<=m;i++)
    {
        fin>>x>>y>>z;
        L[x].push_back({y,z});
        L[y].push_back({x,z});
    }
}

void Initializare()
{
    for(int i=1;i<=n;i++)
        dist[i]=oo;
}

void Dijkstra(int x)
{
    Perechi P;
    Initializare();
    dist[x]=0;
    q.push({x,0});

    while(!q.empty())
    {
        P=q.top();
        q.pop();

        for(auto i:L[P.nod])
            if(dist[i.nod]>dist[P.nod]+i.cost)
            {
                dist[i.nod]=dist[P.nod]+i.cost;
                q.push({i.nod,dist[i.nod]});
            }
    }
}

void Formare_cost()
{
    for(int i=0;i<=k;i++)
    {
        Dijkstra(C[i]);
        for(int j=0;j<=k;j++)
            cost[i][j]=dist[C[j]];
    }
}

void Dp()
{
    const int K=(1<<k);

    /// Initializare

    for(int stare=1;stare<K;stare++)
        for(int nod=0;nod<=k;nod++)
            dp[stare][nod]=oo;

    for(int nod=0;nod<=k;nod++)
        dp[(1<<nod)][nod]=cost[0][nod];


    for(int stare=1;stare<K;stare++)              /// Setez starea
        for(int nod_1=0;nod_1<=k;nod_1++)         /// Setez nod
            if(stare & (1<<nod_1))                /// Verific daca e vizitat (bit ul ==1)
                for(int nod_0=0;nod_0<=k;nod_0++) /// Setez nod nou
                    if(!(stare & (1<<nod_0)))     /// Verific daca nu e vizitat (bit ul ==0)
                        dp[stare | (1<<nod_0)][nod_0]=min(dp[stare | (1<<nod_0)][nod_0],dp[stare][nod_1]+cost[nod_1][nod_0]); /// Actualizez dp

    int sol=oo;

    for(int i=0;i<k;i++)
        sol=min(sol,dp[K-1][i]+cost[i][k]);
    fout<<sol<<"\n";

}

int main()
{
    Citire();
    Formare_cost();
    Dp();

    fin.close();
    fout.close();
    return 0;
}