Cod sursa(job #2984626)

Utilizator Radu_FilipescuFilipescu Radu Radu_Filipescu Data 24 februarie 2023 16:16:18
Problema Ubuntzei Scor 45
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.29 kb
#include <bits/stdc++.h>

using namespace std;

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

const int NMAX = 2005;
const int INF = 2000000000;

int N, M;
int K;
int friends[NMAX];

vector <int> ad[NMAX];
vector <int> cost[NMAX];

unordered_map <int, unordered_map<int, int> > dp;
priority_queue <pair<int, pair<int, int> > > pq;

int cost_stare(int nod, int ubuntzei) {
    // daca starea nu exista in hash
    // returnam infinit

    if(dp.find(nod) == dp.end())
        return INF;

    if(dp[nod].find(ubuntzei) == dp[nod].end())
        return INF;

    return dp[nod][ubuntzei];
}

int main()
{
    fin >> N >> M;
    fin >> K;

    for(int i = 1; i <= K; i++) {
        int x;
        fin >> x;

        friends[x] = i;
    }

    for(int i = 1; i <= M; i++) {
        int x, y, c;

        fin >> x >> y >> c;

        ad[x].push_back(y);
        cost[x].push_back(c);

        ad[y].push_back(x);
        cost[y].push_back(c);
    }

    int ubuntzei_final = 0;
    for(int i = 1; i <= K; i++)
        ubuntzei_final = ubuntzei_final | (1 << i);

    // bagam in pq starea initiala

    dp[1][0] = 0;
    pq.push({0, {1, 0}});

    while(!pq.empty()) {
        // luam starea curenta din pq

        int nod = pq.top().second.first;
        int ubuntzei = pq.top().second.second;
        pq.pop();

        if(nod == N && ubuntzei == ubuntzei_final)
            break;

        // verificam in ce stari putem ajunge
        // din cea curenta
        for(int i = 0; i < ad[nod].size(); i++) {
            int w = ad[nod][i];
            int ubuntzei_w = ubuntzei;

            // daca w este un nod unde era unul din prieteni
            // trebuie updatata starea viitoare

            if(friends[w] > 0)
                ubuntzei_w = ubuntzei_w | (1 << friends[w]);

            // daca costul pe care il obtinem acum
            // este mai bun decat costul vechi
            // SAU starea viitoare este una noua

            if(cost_stare(w, ubuntzei_w) > dp[nod][ubuntzei] + cost[nod][i]) {
                dp[w][ubuntzei_w] = dp[nod][ubuntzei] + cost[nod][i];

                pq.push({-dp[w][ubuntzei_w], {w, ubuntzei_w}});
            }
        }
    }

    fout << dp[N][ubuntzei_final];

    return 0;
}