Cod sursa(job #2981993)

Utilizator velciu_ilincavelciu ilinca velciu_ilinca Data 19 februarie 2023 13:14:03
Problema Ubuntzei Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.11 kb
#include <fstream>
#include <cstring>
#include <queue>
#include <vector>
using namespace std;

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

vector<int>friends;//vector prieteni

struct heapnode
{
    int node;
    int cost;
    bool operator < (const heapnode &other)const
    {
        return cost > other.cost;
    }

};
priority_queue<heapnode>heapmin;

struct elem
{
    int value;
    int pret;
};
vector<elem>g[2002];

int dist[2002];

void dijkstra(int start)
{
    memset(dist, 0x3f, sizeof dist);
    dist[start] = 0;
    heapnode first;
    first.node = start;
    first.cost = 0;
    heapmin.push(first);
    while(!heapmin.empty())
    {
        int nodcurent = heapmin.top().node;
        int costcurent = heapmin.top().cost;

        heapmin.pop();

        if(costcurent > dist[nodcurent])
            continue;

        for(int i = 0; i < g[nodcurent].size(); i++)
        {
            elem vecin = g[nodcurent][i];
            int newcost = costcurent + vecin.pret;
            if(dist[vecin.value] > newcost)
            {
                heapnode newnode;
                newnode.node = vecin.value;
                newnode.cost = newcost;
                heapmin.push(newnode);
                dist[vecin.value] = newcost;
            }
        }
    }
}
int n;
int cost[19][2002];
int dp[600001][19];//costul minim ai sa fi trecut prin toate nodurile aferente bitilor setati din config unde last e poz min
int nr_friends;
int build_dp()
{
    memset(dp, 0x3f, sizeof dp);

    int start = 0;
    dp[1<<start][0] = 0;
    for(int config = 1; config <= (1 << nr_friends) - 1; config++)// config e bitmaskul in care nodul i se afla in traseu daca nodul i este setat
        for(int curr = 0; curr < nr_friends; curr++)//dp[config][curr] nu exista..nu am pb pt ca infinit
            for(int index = 0; index < nr_friends; index++)//vecinii elem curr
            {///finish maine
                if(curr == index)
                    continue;
                if((config & (1<<index)) == 0)
                    dp[config | (1<<index)][index] = min(dp[config | (1<<index)][index], dp[config][curr] + cost[curr][index]);
            }



    return dp[(1 << nr_friends) - 1][nr_friends - 1];

}
int main()
{
    int m;
    in>>n>>m;
    in>>nr_friends;
    friends.push_back(1);
    for(int i=1; i <= nr_friends; i++)
    {
        int friend1;
        in>>friend1;
        friends.push_back(friend1);
    }
    friends.push_back(n);//backwards
    nr_friends+=2;

    for(int i = 1; i <= m; i++)//muchii
    {
        elem x,y;
        in>>x.value>>y.value>>x.pret;
        y.pret = x.pret;

        g[x.value].push_back(y);
        g[y.value].push_back(x);

    }

    for(int i = friends.size()-1; i>=0; i--)
    {
        dijkstra(friends[i]);//iau fiecare prieten si formez distantele minime intre fiecare nod si prieten
        for(int j = friends.size()-1; j>=0; j--)//imi formez toate muchiile cat mai mici existente pt hamilton
            cost[i][j] = dist[friends[j]];
    }
    out<<build_dp()<<'\n';
    return 0;
}