Cod sursa(job #848463)

Utilizator stoicatheoFlirk Navok stoicatheo Data 5 ianuarie 2013 15:07:35
Problema Gather Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.98 kb
#include <fstream>
#include <vector>
#include <queue>
 
using namespace std;
 
const char InFile[]="gather.in";
const char OutFile[]="gather.out";
const int MaxN=752;
const int MaxK=16;
const int MaxConf=(1<<MaxK);
const long long INF=(1LL<<50);
 
ifstream fin(InFile);
ofstream fout(OutFile);
 
struct EdgeTo
{
    EdgeTo(int to=0, int cost=0, int lim=0):to(to),cost(cost),lim(lim){}
 
    int to,cost,lim;
};
 
int N,K,M,x,y,c,lim,Room[MaxK],inQ[MaxN],nr1[MaxConf];
long long sol,C[MaxK][MaxK+1][MaxN],SOL[MaxK][MaxConf];
vector<EdgeTo> G[MaxN];
queue<int> Q;
 
inline void BellmanFord(int nod, int lim, long long *D)
{
    for(register int i=1;i<=N;++i)
    {
        D[i]=INF;
    }
    D[nod]=0;
 
    Q.push(nod);
    inQ[nod]=1;
    while(!Q.empty())
    {
        nod=Q.front();
        Q.pop();
        inQ[nod]=0;
 
        for(vector<EdgeTo>::iterator it=G[nod].begin();it!=G[nod].end();++it)
        {
            if(it->lim<lim)
            {
                continue;
            }
            if(D[it->to]>D[nod]+it->cost)
            {
                D[it->to]=D[nod]+it->cost;
                if(!inQ[it->to])
                {
                    inQ[it->to]=1;
                    Q.push(it->to);
                }
            }
        }
    }
    for(register int i=1;i<=N;++i)
    {
        D[i]*=(lim+1);
    }
}
 
inline int CountBits(int nr)
{
    int sol=0;
    while(nr)
    {
        ++sol;
        nr&=(nr-1);
    }
    return sol;
}
 
int main()
{
    fin>>K>>N>>M;
    for(register int i=0;i<K;++i)
    {
        fin>>Room[i];
    }
    for(register int i=0;i<M;++i)
    {
        fin>>x>>y>>c>>lim;
        G[x].push_back(EdgeTo(y,c,lim));
        G[y].push_back(EdgeTo(x,c,lim));
    }
    fin.close();
 
    for(register int lim=1;lim<K;++lim)
    {
        for(register int j=0;j<K;++j)
        {
            BellmanFord(Room[j],lim,C[lim][j+1]);
        }
    }
    BellmanFord(1,0,C[0][0]);
 
    int EndConf=(1<<K)-1;
    for(register int i=1;i<=EndConf;++i)
    {
        nr1[i]=CountBits(i);
    }
 
    for(register int i=0;i<=K;++i)
    {
        for(register int j=0;j<=EndConf;++j)
        {
            SOL[i][j]=INF;
        }
    }
    SOL[0][0]=0;
 
    for(register int conf=0;conf<=EndConf;++conf)
    {
        int start=1;
        if(conf==0)
        {
            start=0;
        }
        for(register int nod=start;nod<=K;++nod)
        {
            int nextConf=conf;
            if(nod!=0)
            {
                nextConf=nextConf|(1<<(nod-1));
            }
            for(register int nextNod=1;nextNod<=K;++nextNod)
            {
                SOL[nextNod][nextConf]=min(SOL[nextNod][nextConf],SOL[nod][conf]+C[nr1[nextConf]][nod][Room[nextNod-1]]);
            }
        }
    }
 
    sol=INF;
    for(register int i=1;i<=K;++i)
    {
        sol=min(sol,SOL[i][EndConf]);
    }
 
    fout<<sol;
    fout.close();
    return 0;
}