Cod sursa(job #1899995)

Utilizator catalinrebegeaUNIBUC-Claudia Catarig catalinrebegea Data 3 martie 2017 08:42:33
Problema Gather Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.09 kb
#include <bits/stdc++.h>
#define Nmax 755
#define pb push_back

using namespace std;

int k,n,m,wh[Nmax],dp[(1<<15)][15],D[Nmax],dist[15][15][15],nrb[(1<<15)];

struct edge
{
    int nod,dist,cap;
    bool operator <(const edge &A) const
    {
        return dist>A.dist;
    }
};
vector <edge> L[Nmax];
priority_queue <edge> Q;

inline void Dijkstra(int nod, int nr)
{
    int i;
    edge w,w1;
    for(i=1;i<=n;++i) D[i]=-1;
    D[nod]=0;
    w.nod=nod; w.dist=0; Q.push(w);
    while(!Q.empty())
    {
        w=Q.top(); Q.pop();
        for(auto it : L[w.nod])
        {
            if(nr>it.cap) continue;
            w1.nod=it.nod; w1.dist=w.dist+it.dist;
            if(D[w1.nod]==-1 || D[w1.nod]>w1.dist)
            {
                D[w1.nod]=w1.dist; Q.push(w1);
            }
        }
    }
}

inline int nr_bits(int x)
{
    int sol=0;
    for(;x;x=(x&(x-1)),++sol);
    return sol;
}

int main()
{
    int i,j,t,x,y;
    edge w;
    ifstream cin("gather.in");
    ofstream cout("gather.out");
    cin>>k>>n>>m;
    for(i=1;i<=k;++i) cin>>wh[i];
    while(m--)
    {
        cin>>x>>y>>w.dist>>w.cap;
        w.nod=y; L[x].pb(w);
        w.nod=x; L[y].pb(w);
    }

    for(i=0;i<(1<<k);++i) nrb[i]=nr_bits(i);

    for(i=0;i<(1<<k);++i)
        for(j=0;j<k;++j) dp[i][j]=-1;

    Dijkstra(1,0);
    for(i=0;i<k;++i) dp[(1<<i)][i]=D[wh[i+1]];
    for(i=0;i<k;++i)
        for(t=0;t<=k;++t)
        {
            Dijkstra(wh[i+1],t);
            for(j=0;j<k;++j) dist[i][t][j]=D[wh[j+1]];
        }

    for(i=0;i<(1<<k);++i)
        for(j=0;j<k;++j)
            if(dp[i][j]!=-1)
                for(t=0;t<k;++t)
                    if(!((1<<t)&i))
                        if(dp[((1<<t)|i)][t]==-1 || dp[((1<<t)|i)][t] > dp[i][j]+dist[j][nrb[i]][t])
                            dp[((1<<t)|i)][t]=dp[i][j]+dist[j][nrb[i]][t]*(1+nrb[i]);

    int sol=-1;
    for(i=0;i<k;++i)
    {
        if(dp[(1<<k)-1][i]==-1) continue;
        if(sol==-1 || sol>dp[(1<<k)-1][i]) sol=dp[(1<<k)-1][0];
    }
    cout<<sol<<"\n";

    return 0;
}