Cod sursa(job #3200608)

Utilizator Anul2024Anul2024 Anul2024 Data 5 februarie 2024 12:23:27
Problema Gather Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.09 kb
#include <fstream>
#include <vector>
#include <climits>
#include <set>
using namespace std;
ifstream fin ("gather.in");
ofstream fout ("gather.out");
struct muchie
{
    int vecin,cost,val;
};
vector <muchie> v[751];
set <pair<int,int>> s;
int nr,j,nrc,l[751],inf,i,minim,x,y,c,p,k,n,m,dpd[32768][15],dp[16][16][751],d[751];
void dijkstra (int valp,int poz,int d[])
{
    for (int i=1; i<=n; i++)
        d[i]=inf;
    d[poz]=0;
    s.insert (make_pair(0,poz));
    while (!s.empty ())
    {
        int nod=s.begin ()->second;
        s.erase (s.begin ());
        for (int i=0; i<v[nod].size (); i++)
        {
            int vecin=v[nod][i].vecin;
            int cost=v[nod][i].cost;
            int val=v[nod][i].val;
            if (val<valp)
                continue;
            if (d[vecin]>d[nod]+cost)
            {
                s.erase (make_pair (d[vecin],vecin));
                d[vecin]=d[nod]+cost;
                s.insert (make_pair (d[vecin],vecin));
            }
        }
    }
}
int main ()
{
    inf=10000000;
    fin>>k>>n>>m;
    for (i=0; i<k; i++)
        fin>>l[i];
    for (i=1; i<=m; i++)
    {
        fin>>x>>y>>c>>p;
        v[x].push_back ({y,c,p});
        v[y].push_back ({x,c,p});
    }
    for (p=0; p<=k; p++)
    {
        for (i=0; i<k; i++)
            dijkstra (p,l[i],dp[p][i]);
    }
    dijkstra (0,1,d);
    for (p=1; p<(1<<k); p++)
    {
        for (i=0; i<k; i++)
            dpd[p][i]=inf;
    }
    for (i=0; i<k; i++)
        dpd[(1<<i)][i]=d[l[i]];
    for (p=1; p<(1<<k); p++)
    {
        for (i=0; i<k; i++)
        {
            if (!((p>>i)&1)||dpd[p][i]!=inf)
                continue;
            nr=p-(1<<i);
            for (j=0; j<k; j++)
            {
                if (!((nr>>j)&1))
                    continue;
                nrc=__builtin_popcount (nr);
                dpd[p][i]=min (dpd[p][i],dpd[nr][j]+dp[nrc][j][l[i]]*(nrc+1));
            }
        }
    }
    minim=inf;
    for (i=0; i<k; i++)
        minim=min (minim,dpd[(1<<k)-1][i]);
    fout<<minim;
    return 0;
}