Cod sursa(job #3339281)

Utilizator adelinapetreAdelina Petre adelinapetre Data 7 februarie 2026 11:32:41
Problema Gather Scor 60
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.41 kb
#include <fstream>
#include <vector>
#include <queue>
using namespace std;

ifstream cin("gather.in");
ofstream cout("gather.out");

const int Nmax = 755, Kmax = 15;

struct muchie
{
    int y, dist, cnt;
};
vector<muchie>g[Nmax];

struct stare
{
    int nod, mask, dist;
    bool operator>(const stare &x ) const
    {
        if(dist != x.dist)
            return dist > x.dist;
        if(mask != x.mask) return mask > x.mask;
        return nod > x.nod;
    }
};
int dist[Nmax][(1<<Kmax)];
bool det[Nmax];
int idx[Nmax];

int n, k;

void dijk()
{
    for(int i = 1; i <= n; i ++)
        for(int mask = 0; mask < (1 << k); mask ++)
            dist[i][mask] = 1e9;
    dist[1][0] = 0;
    priority_queue<stare, vector<stare>, greater<stare>> pq;
    pq.push({1, 0, 0});
    if(idx[1] != 0)
    {
        dist[1][(1 << idx[1])] = 0;
        pq.push({1, (1<<idx[1]), 0});
    }
    while(!pq.empty())
    {
        stare now = pq.top();
        pq.pop();
        //cout << now.nod << " " << now.dist << " " << now.mask << '\n';
        int x = now.nod, mask = now.mask, distc = now.dist;
        int nrb = __builtin_popcount(mask) + 1;
        for(auto it: g[x])
        {
            int y = it.y, distm = it.dist, cnt = it.cnt;
            if(det[y] == 1)
            {
                //cout << "aaa " << y << '\n';
                int mask2 = mask | (1 << idx[y]);
                if(nrb - 1 <= cnt && distc + distm * nrb < dist[y][mask2])
                {
                    dist[y][mask2] = distc + distm * nrb;
                    pq.push({y, mask2, dist[y][mask2]});
                }
            }
            else
            {
                if(nrb - 1 <= cnt && distc + distm * nrb < dist[y][mask])
                {
                    dist[y][mask] = distc + distm * nrb;
                    pq.push({y, mask, dist[y][mask]});
                }
            }
        }
    }
}

int main()
{
    int m, x, y, c, d;
    cin >> k >> n >> m;
    for(int i = 1; i <= k; i ++)
    {
        cin >> x;
        det[x] = 1;
        idx[x] = i - 1;
    }
    for(int i = 1; i <= m; i ++)
    {
        cin >> x >> y >> c >> d;
        g[x].push_back({y, c, d});
        g[y].push_back({x, c, d});
    }
    dijk();

    int ans = 1e9, mask = (1 << k) - 1;
    for(int i = 1; i <= n; i ++)
        ans = min(ans, dist[i][mask]);
    cout << ans;
    return 0;
}