Pagini recente » Cod sursa (job #2004254) | Cod sursa (job #2940217) | Cod sursa (job #168448) | Cod sursa (job #2836239) | Cod sursa (job #525878)
Cod sursa(job #525878)
#include <fstream>
#include <iostream>
#include <set>
#include <vector>
#include <limits>
using namespace std;
typedef long long lli;
lli const maxv=750,maxn=15,maxm=1250,
inf = (numeric_limits<lli>::max())/20;
struct hamiltonian_path
{
struct weight
{
lli x,w;
bool operator<(weight const&o)const
{return (w==o.w)?(x<o.x):(w<o.w);}
};
struct weights
{
lli n,V[maxv];
set<weight> W;
lli pop_min()
{ weight const&e=*W.begin();
//cout<<"pop: " << e.x << " " << e.w << endl;
lli x=e.x;W.erase(W.begin());
return x;
}
void decrease(lli x,lli w)
{ if(V[x]>w)
{ //cout<<"decrease: " << x << " " << w << endl;
weight e;e.x=x;e.w=V[x];
W.erase(W.find(e));
e.w=V[x]=w;W.insert(e);
}
}
void init(lli an)
{ //cout<<"init"<<endl;
n=an;W.clear();
lli x;weight e;
for(x=0;n>x;++x)
{e.x=x;e.w=V[x]=inf;W.insert(e);}
}
bool empty() const
{ return W.empty(); }
};
struct edge
{lli y,w,c;};
weights V;
vector<edge> A[maxv];
lli
m,v,
n,Y[maxn],W0[maxn],
W[1+maxn][maxn][maxn],
D[1<<maxn][1+maxn];
lli C[1<<maxn];
void compute_cardinal()
{ lli t=(1<<n)-1,s,lsb;
C[0]=0;
for(s=1;t>=s;++s)
{ lsb=(s&-s);
C[s]=1+C[s^lsb];
}
}
void dijkstra(lli s,lli h)
{ lli x,t,i,y,w,c;
V.init(v);
V.decrease(s,0);
while(!V.empty())
{ x=V.pop_min();
t=(lli)A[x].size();
for(i=0;t>i;++i)
{ y=A[x][i].y;
w=A[x][i].w;
c=A[x][i].c;
if(h<=c)
{ V.decrease(y,V.V[x]+w); }
}
}
}
void add_weights(lli i,lli h)
{ lli j;
for(j=0;n>j;++j)
{W[h][i][j]=V.V[Y[j]];}
}
void compute_weights()
{ lli h,i;
dijkstra(0,0);
for(i=0;n>i;++i)
{W0[i]=V.V[Y[i]];}
for(h=1;n>=h;++h)
{ for(i=0;n>i;++i)
{ dijkstra(Y[i],h);
add_weights(i,h);
}
}
}
lli get_minimum_weight()
{ compute_weights();
compute_cardinal();
lli x,t,s,v,y,bx,by,b;
t=(1<<n)-1;
for(s=1;t>=s;++s)
{ for(x=0;n>x;++x)
{D[s][x]=inf;}
}
for(x=0;n>x;++x)
{D[1<<x][x]=W0[x];}
for(s=1;t>=s;++s)
{ for(x=0;n>x;++x)
{ bx=(1<<x);
if(s&bx)
{ for(y=0;n>y;++y)
{ by=(1<<y);
if(0==(s&by))
{ v=D[s][x]+(C[s]+1)*W[C[s]][x][y];
if(v<D[s|by][y]){D[s|by][y]=v;}
}
}
}
}
}
b=inf;
for(y=0;n>y;++y)
{ if(b>D[t][y]){b=D[t][y];} }
return b;
}
};
hamiltonian_path H;
int main()
{ ifstream is("gather.in");
ofstream os("gather.out");
lli k,n,m,i,y,a,b,c,d;
hamiltonian_path::edge e;
is>>k>>n>>m;
H.n=k;H.v=n;
for(i=0;k>i;++i)
{is>>y;--y;H.Y[i]=y;}
for(i=0;m>i;++i)
{ is>>a>>b>>c>>d;
--a;--b;e.w=c;e.c=d;
e.y=b;H.A[a].push_back(e);
e.y=a;H.A[b].push_back(e);
}
a=H.get_minimum_weight();
os<<a<<endl;
return 0;
}