Cod sursa(job #3343237)

Utilizator TeodoRazvanStancu Teodor-Razvan TeodoRazvan Data 26 februarie 2026 18:16:29
Problema Gather Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.19 kb
#include <bits/stdc++.h>

using namespace std;

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

const long long int inf=1e15;

struct str {
    int nod;
    long long int cost;
    bool operator<(const str & aux) const {
        return cost>aux.cost;
    }
};

struct muc {
    int x,c,lim;
};

int n,k,m;
long long int dist[17][17][755],dp[1<<16][16];
vector<vector<muc>>a;
vector<int>vs;

void dijkstra(int p,int st,long long d[]) {
    for (int i=1;i<=n;i++) d[i]=inf;
    d[st]=0;
    priority_queue<str>pq;
    pq.push({st,0});
    while (!pq.empty()) {
        int nod=pq.top().nod;
        long long int cost=pq.top().cost;
        pq.pop();
        if (cost>d[nod]) continue;
        for (auto f:a[nod]) {
            if (f.lim>=p&&d[nod]+f.c<d[f.x]) {
                d[f.x]=d[nod]+f.c;
                pq.push({f.x,d[f.x]});
            }
        }
    }
}

int main() {
    fin>>k>>n>>m;
    a.resize(n+1);
    vs.resize(k+1);
    vs[0]=1;
    int x;
    for (int i=0;i<k;i++) {
        fin>>x;
        vs[i+1]=x;
    }
    int na,nb,nc,nl;
    for (int i=0;i<m;i++) {
        fin>>na>>nb>>nc>>nl;
        a[na].push_back({nb,nc,nl});
        a[nb].push_back({na,nc,nl});
    }
    for (int i=0;i<=k;i++) {
        for (int j=0;j<=k;j++) {
            dijkstra(i,vs[j],dist[i][j]);
        }
    }
    for (int i=0;i<(1<<k);i++) {
        for (int j=0;j<=k;j++)dp[i][j]=inf;
    }

    for (int i=0;i<k;i++) if (dist[0][0][vs[i+1]]!=inf) dp[1<<i][i]=dist[0][0][vs[i+1]];
    for (int i=1;i<(1<<k);i++) {
        int p=__builtin_popcount(i);
        if (p==k)continue;
        for (int j=0;j<k;j++) {
            if (!(i&(1<<j))||dp[i][j]==inf) continue;
            for (int u=0;u<k;u++) {
                if (!(i&(1<<u))) {
                    long long int nd=dist[p][j+1][vs[u+1]];
                    if (nd!=inf) {
                        long long int ndc=dp[i][j]+nd*(p+1);
                        if (ndc<dp[i|(1<<u)][u])dp[i|(1<<u)][u]=ndc;
                    }
                }
            }
        }
    }
    long long int rez=inf;
    for (int i=0;i<k;i++) rez=min(rez,dp[(1<<k)-1][i]);
    fout<<rez;
    return 0;
}