Cod sursa(job #995808)

Utilizator DaNutZ2UuUUBB Bora Dan DaNutZ2UuU Data 10 septembrie 2013 11:56:52
Problema Gather Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.86 kb
#include<fstream>
#include<vector>
#include<cstring>
#include<queue>
#define mp make_pair
#define INF 0x3f3f3f
using namespace std;
ifstream f("gather.in");
ofstream g("gather.out");
int i,j,k,x,y,c,d,lim,sol,n,m,p,pu[20],a[1<<17][17],din[17][17][755];
struct nod{int x,y,z;};
vector<nod>l[755];
priority_queue<pair<int,int> >h;
inline int nrb(int x)
{
    int rez=0;
    while(x)
    {
        ++rez;
        x&=(x-1);
    }
    return rez;
}
void dijkstra(int s,int li,int v[])
{
    int x,d;
    for(int i=0;i<=n;++i)
    v[i]=INF;
    v[s]=0;
    h.push(mp(0,s));
    while(!h.empty())
    {
        d=-h.top().first;
        x=h.top().second;
        h.pop();
        if(v[x]<d)
        continue;
        for(vector<nod>::iterator it=l[x].begin();it!=l[x].end();++it)
        {
            if((*it).z<li)
            continue;
            if(v[x]+(*it).y<v[(*it).x])
            {
                v[(*it).x]=v[x]+(*it).y;
                h.push(mp(-v[(*it).x],(*it).x));
            }
        }
    }
    for(int i=1;i<=n;++i)
    if(v[i]<INF)
    v[i]*=(li+1);
}
int main()
{
    f>>k>>n>>m;
    for(i=1;i<=k;++i)
    f>>pu[i],--pu[i];
    for(i=1;i<=m;++i)
    {
        f>>x>>y>>c>>d;
        l[x-1].push_back((nod){y-1,c,d});
        l[y-1].push_back((nod){x-1,c,d});
    }
    for(i=0;i<=k+1;++i)
    for(j=0;j<=k+1;++j)
    dijkstra(pu[i],j,din[i][j]);
    memset(a,INF,sizeof(a));
    a[1][0]=0;
    for(i=2;i<(1<<(k+1));++i)
    {
        lim=nrb(i)-2;
        for(j=0;j<=k;++j)
        {
            if(i&(1<<j))
            for(p=0;p<=k;++p)
            if(a[i^(1<<j)][p]!=INF&&din[p][lim][pu[j]]!=INF)
            a[i][j]=min(a[i][j],a[i^(1<<j)][p]+din[p][lim][pu[j]]);
        }
    }
    sol=a[(1<<(k+1))-1][0];
    for(i=1;i<=k;++i)
    sol=min(sol,a[(1<<(k+1))-1][i]);
    g<<sol<<'\n';
    return 0;
}