Cod sursa(job #1897034)

Utilizator GinguIonutGinguIonut GinguIonut Data 1 martie 2017 09:12:59
Problema Gather Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.46 kb
#include <fstream>
#include <vector>
#include <queue>

#define INF 40000000000000000
#define nMax 752
#define kMax 16
#define confMax (1 << 15)
#define pb push_back
#define mkp make_pair
#define x first
#define y second

using namespace std;

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

int nrMust, n, m;
int city[kMax];
long long dist[kMax][kMax][nMax], dp[confMax][kMax], mainDist[nMax];
vector<pair<int, pair<int, int> > > G[nMax];
priority_queue<pair<int, int>, vector<pair<int, int> >, greater<pair<int, int> > > pQueue;

void dijkstra(int node, long long dist[], int capMin)
{
    for(int i=1; i<=n; i++)
        dist[i]=INF;
    dist[node]=0;
    pQueue.push(mkp(dist[node], node));

    while(!pQueue.empty())
    {
        int node=pQueue.top().y, d=pQueue.top().x;
        pQueue.pop();
        if(dist[node]!=d)
            continue;

        for(vector<pair<int, pair<int, int> > >::iterator it=G[node].begin(); it!=G[node].end(); it++)
        {
            int cap=it->first, fiu=it->second.first, cost=it->second.second;
            if(capMin<=cap && dist[node]+cost<dist[fiu])
            {
                dist[fiu]=dist[node]+cost;
                pQueue.push(mkp(dist[fiu], fiu));
            }
        }
    }
}

int main()
{
    int a, b, c, d;
    fin>>nrMust>>n>>m;

    for(int i=0; i<nrMust; i++)
        fin>>city[i];

    for(int i=1; i<=m; i++)
    {
        fin>>a>>b>>c>>d;
        G[a].pb(mkp(d, mkp(b, c)));
        G[b].pb(mkp(d, mkp(a, c)));
    }

    dijkstra(1, mainDist, 0);
    for(int i=0; i<nrMust; i++)
        for(int j=0; j<=nrMust; j++)
            dijkstra(city[i], dist[i][j], j);

    int limit=(1 << nrMust)-1;
    for(int conf=0; conf<=limit; conf++)
        for(int i=0; i<nrMust; i++)
            dp[conf][i]=INF;
    for(int i=0; i<nrMust; i++)
        dp[1 << i][i]=mainDist[city[i]];

    for(int conf=1; conf<limit; conf++)
    {
        int nrBiti=0;
        for(int i=0; i<nrMust; i++)
            if(conf & (1 << i))
                nrBiti++;
        for(int i=0; i<nrMust; i++)
            if(conf & (1 << i))
                for(int j=0; j<nrMust; j++)
                    if(i!=j && !(conf & (1 << j)))
                        dp[conf | (1 << j)][j]=min(dp[conf | (1 << j)][j], dp[conf][i]+1ll*dist[i][nrBiti][city[j]]*(nrBiti+1));
    }

    long long Sol=INF;
    for(int i=0; i<nrMust; i++)
        Sol=min(Sol, dp[limit][i]);
    fout<<Sol;
}