Cod sursa(job #3305156)

Utilizator anca.gdDumitru Anca Gabriela anca.gd Data 30 iulie 2025 13:07:01
Problema Gather Scor 70
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.29 kb
#include<bits/stdc++.h>
using namespace std;
ifstream fin("gather.in");
ofstream fout("gather.out");
int n,m,k, det[17], mx_det[17][17], detinuti[755];
long long int precalc[17][17], dist[755];
pair<long long int,int> dp[1<<16][17];
vector<tuple<int,int,int>> v[755];
void precalc_dijkstra(int x){
    priority_queue<tuple<long long int,int,int>> q;
    for(int i=1; i<=n;i++)
        dist[i]=1e9;
    q.push({0,det[x], 1e9});
    dist[det[x]]=0;
    while(!q.empty()){
        long long int dis; int nod, md;
        tie(dis,nod,md)=q.top();
        q.pop();
        dis=-dis;
        if(dis>dist[nod]) continue;
        for(auto vec: v[nod]){
            long long int neigh; int cost, mxd;
            tie(neigh, cost, mxd)=vec;
            if(dist[neigh]>=dist[nod]+cost){
                dist[neigh]=dist[nod]+cost;
                mxd=min(md, mxd);
                detinuti[neigh]=mxd;
                q.push({-dist[neigh], neigh, mxd});
            }
        }
    }
    for(int i=x+1; i<=k; i++){
        precalc[x][i]=precalc[i][x]=dist[det[i]];
        mx_det[x][i]=mx_det[i][x]=detinuti[det[i]];
    }
}
int main()
{
    fin>>k>>n>>m;
    k++;
    det[1]=1;
    for(int i=2; i<=k; i++) fin>>det[i];
    sort(det+1, det+k+1);
    while(m--){
        int x,y,z,w;
        fin>>x>>y>>z>>w;
        v[x].push_back({y,z,w});
        v[y].push_back({x,z,w});
    }
    for(int i=1; i<k;i++)
        precalc_dijkstra(i);
    for(int i=0; i<(1<<k); i++)
        for(int j=0; j<=k; j++)
            dp[i][j]={1e9,1e9};
    dp[1][1]={0, 1e9};
    for(int mask=3; mask<(1<<k); mask++){
        int nob=__builtin_popcount(mask)-1; //fara i
        if(nob<0) continue;
        for(int i=0; i<k; i++)
            if(mask&(1<<i))
                for(int j=0; j<k;j++)
                    if(mask&(1<<j) && i!=j){
                        if((dp[mask][i+1].first>dp[mask^(1<<i)][j+1].first+precalc[i+1][j+1]*nob) && nob-1<=mx_det[i+1][j+1]){
                            dp[mask][i+1]={dp[mask^(1<<i)][j+1].first+precalc[i+1][j+1]*nob, min(mx_det[i+1][j+1], dp[mask^(1<<i)][j+1].second)};
                        }
                    }
    }
    long long int ans=1e9;
    for(int i=1; i<=k; i++)
        ans=min(ans, dp[(1<<k)-1][i].first);
    fout<<ans;
    return 0;
}