Pagini recente » Cod sursa (job #1889658) | Cod sursa (job #1443894) | Cod sursa (job #656240) | Cod sursa (job #1992277) | Cod sursa (job #679250)
Cod sursa(job #679250)
#include <fstream>
#include <vector>
#include <cstring>
#include <algorithm>
#define maxN 751
#define maxK 16
#define INF 0x7fffffff
using namespace std;
vector <int> g[maxN];
int dist[maxN][maxN];
int cnt[maxN][maxN];
int cost[maxK][maxK][maxK];
int d[maxN];
int h[maxN];
int v[maxK];
int K,N;
inline bool cmp(const int &a,const int &b)
{
return d[a]>d[b];
}
inline void dij(int nod,int num)
{
memset(h,0,sizeof(h));
for(int i=1;i<=N;++i) d[i]=INF;
h[0]=1;
h[1]=nod;
d[nod]=0;
for(;h[0];)
{
nod=h[1];
pop_heap(h+1,h+h[0]+1,cmp);
--h[0];
for(vector <int>::iterator it=g[nod].begin();it!=g[nod].end();++it)
if(d[*it]>d[nod]+(num+1)*dist[nod][*it]&&num<=cnt[nod][*it])
{
d[*it]=d[nod]+(num+1)*dist[nod][*it];
h[++h[0]]=*it;
push_heap(h+1,h+h[0]+1,cmp);
}
}
}
struct hp
{
int nod,cod;
};
int ds[100001][maxK];
inline bool cmpx(const hp &a,const hp &b)
{
int xa=0;
for(int aux=a.cod;aux;aux>>=1)
if(aux&1) ++xa;
int xb=0;
for(int aux=b.cod;aux;aux>>=1)
if(aux&1) ++xb;
if(ds[xa][a.nod]!=ds[xb][b.nod]) return ds[xa][a.nod]>ds[xb][b.nod];
return xa>xb;
}
inline void dijx()
{
hp h[maxK*maxK+1];
int size=0;
memset(h,0,sizeof(h));
for(int i=0;i<=(1<<K)-1;++i)
for(int j=0;j<=K;++j)
ds[i][j]=INF;
ds[0][0]=0;
size=1;
h[1].nod=0;
h[1].cod=0;
for(int nod,cod;size;)
{
nod=h[1].nod;
cod=h[1].cod;
pop_heap(h+1,h+size+1,cmpx);
--size;
int x=0;
for(int aux=cod;aux;aux>>=1)
if(aux&1) ++x;
for(int i=1;i<=K;++i)
if((cod&(1<<(i-1)))==0)
if(ds[cod+(1<<(i-1))][i]>ds[cod][nod]+cost[x][nod][i]&&cost[x][nod][i])
{
ds[cod+(1<<(i-1))][i]=ds[cod][nod]+cost[x][nod][i];
if(x+1<K)
{
h[++size].nod=i;
h[size].cod=cod+(1<<(i-1));
push_heap(h+1,h+size+1,cmpx);
}
}
}
}
ifstream in;
ofstream out;
int main()
{
int M,x,y;
in.open("gather.in");
in>>K>>N>>M;
v[0]=1;
for(int i=1;i<=K;++i) in>>v[i];
for(;M--;)
{
in>>x>>y;
in>>dist[x][y];
in>>cnt[x][y];
cnt[y][x]=cnt[x][y];
dist[y][x]=dist[x][y];
g[x].push_back(y);
g[y].push_back(x);
}
in.close();
out.open("gather.out");
memset(cost,0,sizeof(cost));
for(int i=0;i<K;++i)
for(int j=0;j<=K;++j)
{
dij(v[j],i);
for(int k=1;k<=K;++k)
if(d[v[k]]!=INF&&d[v[k]])
cost[i][j][k]=d[v[k]];
}
dijx();
int min=INF;
for(int i=1;i<=K;++i)
if(min>ds[(1<<K)-1][i]) min=ds[(1<<K)-1][i];
out<<min<<'\n';
out.close();
return 0;
}