Cod sursa(job #2371390)

Utilizator victorv88Veltan Victor victorv88 Data 6 martie 2019 17:25:09
Problema Ubuntzei Scor 45
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.09 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <bitset>
#include <set>
#define pb push_back

using namespace std;

ifstream f("ubuntzei.in");
ofstream g("ubuntzei.out");

int n, m, nr_prieteni, localitati_prieteni[20], dp[10000][2005], suma;

struct d
{
    int to, cost;
};

struct alt_d
{
    int to, cost, localitati_vizitate;
};

class cmp{
public:
    bool operator() (alt_d a, alt_d b)
    {
        if (a.to==b.to && a.cost==b.cost)
            return a.localitati_vizitate<b.localitati_vizitate;
        if (a.cost==b.cost)
            return a.to<b.to;
        return a.cost<b.cost;
    }
};

set<alt_d,cmp>q;

int aici_se_afla_prieten[2005];
vector<d>graph[2005];

void solve()
{
    dp[0][1]=0;
    q.insert({1,1,0});
    while (!q.empty())
    {
        auto sus=q.begin();
        int nod_actual=sus->to;
        int cost_actual=sus->cost;
        int localitati_vizitate_actual=sus->localitati_vizitate;
        q.erase(q.begin());
        for (auto &v:graph[nod_actual])
        {
            if (aici_se_afla_prieten[v.to] && !(localitati_vizitate_actual&(1<<aici_se_afla_prieten[v.to])))
            {
                if (dp[localitati_vizitate_actual|(1<<aici_se_afla_prieten[v.to])][v.to]==0 || cost_actual+v.cost<dp[localitati_vizitate_actual|(1<<aici_se_afla_prieten[v.to])][v.to])
                {
                    if (dp[localitati_vizitate_actual|(1<<aici_se_afla_prieten[v.to])][v.to]!=0x3f3f3f3f)
                    {
                        q.erase({v.to,dp[localitati_vizitate_actual|(1<<aici_se_afla_prieten[v.to])][v.to],localitati_vizitate_actual|(1<<aici_se_afla_prieten[v.to])});
                    }
                    dp[localitati_vizitate_actual|(1<<aici_se_afla_prieten[v.to])][v.to]=cost_actual+v.cost;
                    q.insert({v.to,dp[localitati_vizitate_actual|(1<<aici_se_afla_prieten[v.to])][v.to],localitati_vizitate_actual|(1<<aici_se_afla_prieten[v.to])});
                }
            }
            else if (!aici_se_afla_prieten[v.to])
            {
                if (dp[localitati_vizitate_actual][v.to]==0 || cost_actual+v.cost<dp[localitati_vizitate_actual][v.to])
                {
                    if (dp[localitati_vizitate_actual][v.to]!=0x3f3f3f3f)
                    {
                        q.erase({v.to,dp[localitati_vizitate_actual][v.to],localitati_vizitate_actual});
                    }
                    dp[localitati_vizitate_actual][v.to]=cost_actual+v.cost;
                    q.insert({v.to,dp[localitati_vizitate_actual][v.to],localitati_vizitate_actual});
                }
            }
        }
    }

    g << dp[suma][n]-1;
}

int main()
{
    int from, to, cost;
    f >> n >> m;
    f >> nr_prieteni;
    for (int i=1; i<=nr_prieteni; ++i)
    {
        f >> localitati_prieteni[i];
        suma+=(1<<i);
        aici_se_afla_prieten[localitati_prieteni[i]]=i;
    }
    for (int i=1; i<=m; ++i)
    {
        f >> from >> to >> cost;
        graph[from].pb({to,cost});
        graph[to].pb({from,cost});
    }
    solve();
    return 0;
}