Cod sursa(job #3306688)

Utilizator Grama2008Grama Andrei Teodor Grama2008 Data 12 august 2025 19:06:48
Problema Gather Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.93 kb
#include <bits/stdc++.h>

using namespace std;

const int K=15, N=750;

vector<tuple<int, int, int>> adj[N];

long long dp[N][1<<K];

int prisoners[N];

int main()
{
    freopen("gather.in", "r", stdin);
    freopen("gather.out", "w", stdout);
    memset(dp, (1<<6)-1, sizeof(dp));
    memset(prisoners, -1, sizeof(prisoners));
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int k,n,m;cin>>k>>n>>m;
    for (int i=0;i<k;i++){
        int a;cin>>a;a--;
        prisoners[a]=i;
    }
    for (int i=0;i<m;i++){
        int a,b,c,d;cin>>a>>b>>c>>d;a--;b--;
        adj[a].push_back(make_tuple(d,b,c));
        adj[b].push_back(make_tuple(d,a,c));
    }
    for (int i=0;i<n;i++){
        sort(adj[i].begin(), adj[i].end());
    }
    dp[0][0]=0;
    using state=pair<long long, int>;
    priority_queue<state, vector<state>, greater<state>> q;
    for (int mask=0;mask<(1<<k);mask++){
        for (int i=0;i<n;i++){
            if (dp[i][mask]<1e18){
                q.push({dp[i][mask], i});
            }
        }
        while (!q.empty()){
            auto [d, node]=q.top();q.pop();
            if (d>dp[node][mask]){
                continue;
            }
            for (int j=0;j<(int)adj[node].size() && __builtin_popcount(mask)<=get<0>(adj[node][j]);j++){
                int newnode=get<1>(adj[node][j]);
                long long w=get<2>(adj[node][j]);
                w=w*(1+__builtin_popcount(mask));
                if (dp[newnode][mask]>dp[node][mask]+w){
                    dp[newnode][mask]=dp[node][mask]+w;
                    q.push({dp[newnode][mask], newnode});
                }
            }
        }
        for (int i=0;i<n;i++){
            if (dp[i][mask]<1e18 && prisoners[i]!=-1){
                dp[i][mask|(1<<prisoners[i])]=min(dp[i][mask|(1<<prisoners[i])], dp[i][mask]);
            }
        }
    }
    long long ans=1e18;
    for (int i=0;i<n;i++){
        ans=min(ans, dp[i][(1<<k)-1]);
    }
    cout<<ans;
    return 0;
}