Cod sursa(job #1969847)

Utilizator LucianTLucian Trepteanu LucianT Data 18 aprilie 2017 17:58:32
Problema Gather Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.4 kb
#include <bits/stdc++.h>
#define maxN 755
#define maxK 16
#define pii pair<int,int>
using namespace std;
const int maxConf=(1<<15);
const long long INF=(1LL<<60);

int cell[maxK];

int must,n,m,i,j,x,y,z,t,lim;
long long dist[maxK][maxK][maxN];
long long dp[maxConf][maxK];
long long distfirst[maxN];
vector<pair<int,pair<int,int> > >v[maxN];
priority_queue<pii,vector<pii>,greater<pii> >Heap;

void dijkstra(int nod, long long dist[],int flow)
{
    for(int i=1;i<=n;i++)
        dist[i]=INF;
    dist[nod]=0;
    Heap.push(make_pair(dist[nod],nod));

    while(!Heap.empty())
    {
        int node=Heap.top().second;
        int actdist=Heap.top().first;
        Heap.pop();
        if(dist[node]!=actdist)
            continue;

        for(auto it:v[node])
        {
            int kap=it.first;
            int son=it.second.first;
            int newcost=it.second.second;

            if(kap>=flow && dist[node]+newcost<dist[son]){
                dist[son]=dist[node]+newcost;
                Heap.push(make_pair(dist[son],son));
            }
        }
    }
}
void getDistances()
{
    dijkstra(1,distfirst,0);
    for(int i=0;i<must;i++)
        for(int j=0;j<=must;j++)
            dijkstra(cell[i],dist[i][j],j);
}

void prepare()
{
    lim=(1<<must)-1;
    for(int mask=0;mask<=lim;mask++)
        for(i=0;i<must;i++)
            dp[mask][i]=INF;

    for(i=0;i<must;i++)
        dp[1<<i][i]=distfirst[cell[i]];

}
int main()
{
    freopen("gather.in","r",stdin);
    freopen("gather.out","w",stdout);
    scanf("%d %d %d",&must,&n,&m);
    for(i=0;i<must;i++)
        scanf("%d",&cell[i]);

    for(i=1;i<=m;i++){
        scanf("%d %d %d %d",&x,&y,&z,&t);
        v[x].push_back(make_pair(t,make_pair(y,z)));
        v[y].push_back(make_pair(t,make_pair(x,z)));
    }

    getDistances();
    prepare();

    for(int mask=1;mask<lim;mask++)
    {
        int cntbiti=0;
        for(i=0;i<must;i++)
            if(mask&(1<<i))
                cntbiti++;

        for(i=0;i<must;i++)
            if(mask&(1<<i))
                for(j=0;j<must;j++)
                    if(i!=j && !(mask&(1<<j)))
                        dp[mask|(1<<j)][j]=min(dp[mask|(1<<j)][j],dp[mask][i]+1LL*dist[i][cntbiti][cell[j]]*(cntbiti+1));
    }

    long long sol=INF;
    for(i=0;i<must;i++)
        sol=min(sol,dp[lim][i]);
    printf("%lld",sol);
    return 0;
}