Pagini recente » Cod sursa (job #1411440) | Cod sursa (job #1775894) | Cod sursa (job #815091) | Cod sursa (job #1258386) | Cod sursa (job #116846)
Cod sursa(job #116846)
using namespace std;
#include <stdio.h>
#include <vector>
#define Kmax 20
#define Nmax 800
#define Mmax 1300
#define infinit 2147000000
#define Pmax 32800
int K,N,M;
int det[Kmax];
int A[Mmax],B[Mmax],C[Mmax],D[Mmax];
int dist[Kmax][Kmax][Kmax];
int heap[Nmax],d[Nmax],ph[Nmax],nrh;
unsigned int a[Pmax][Kmax];
vector<int> g[Nmax];
void citire()
{
int i;
freopen("gather.in","r",stdin);
scanf("%d %d %d",&K,&N,&M);
for (i=1;i<=K;++i)
scanf("%d",&det[i]);
for (i=1;i<=M;++i)
{
scanf("%d %d %d %d",&A[i],&B[i],&C[i],&D[i]);
g[A[i]].push_back(i);
g[B[i]].push_back(i);
}
fclose(stdin);
}
int heap_out()
{
int t,f1,f2,aux,v;
v=heap[1];
heap[1]=heap[nrh];
ph[heap[1]]=1;
--nrh;
if (nrh<2) return v;
t=1;
while ((t<<1)<=nrh)
{
f1=t<<1;
if (f1<nrh)
{
f2=f1+1;
if (d[heap[f1]]<d[heap[f2]])
if (d[heap[f1]]<d[heap[t]])
{
aux=heap[f1];
heap[f1]=heap[t];
heap[t]=aux;
ph[heap[t]]=t;
ph[heap[f1]]=f1;
t=f1;
}
else ;
else if (d[heap[f2]]<d[heap[t]])
{
aux=heap[f2];
heap[f2]=heap[t];
heap[t]=aux;
ph[heap[t]]=t;
ph[heap[f2]]=f2;
t=f2;
}
}
else
if (d[heap[f1]]<d[heap[t]])
{
aux=heap[f1];
heap[f1]=heap[t];
heap[t]=aux;
ph[heap[t]]=t;
ph[heap[f1]]=f1;
t=f1;
}
else break;
}
return v;
}
void heap_update(int nod)
{
int t,f,aux;
if (ph[nod]==0)
{
++nrh;
heap[ph[nod]=nrh]=nod;
f=nrh;
t=f>>1;
while (t>0)
if (d[heap[f]]<d[heap[t]])
{
aux=heap[f];
heap[f]=heap[t];
heap[t]=aux;
ph[heap[f]]=f;
ph[heap[t]]=t;
f=t;
t=f>>1;
}
else break;
}
else
{
f=ph[nod];
t=f>>1;
while (t>0)
if (d[heap[f]]<d[heap[t]])
{
aux=heap[f];
heap[f]=heap[t];
heap[t]=aux;
ph[heap[f]]=f;
ph[heap[t]]=t;
f=t;
t=f>>1;
}
else break;
}
}
void dijkstra(int s,int nrd)
{
int i,nod;
vector<int>::iterator it;
//init
memset(heap,0,sizeof(heap));
memset(ph,0,sizeof(ph));
nrh=0;
for (i=1;i<=N;++i)
d[i]=infinit;
d[det[s]]=0;
heap_update(det[s]);
//dijkstra
while (nrh>0)
{
nod=heap_out();
for (it=g[nod].begin();it<g[nod].end();++it)
if (D[*it]>=nrd)
{
if (C[ *it ] + d[nod] < d[ A[*it] ])
{
d[ A[*it] ] = C[ *it ] + d[nod];
heap_update( A[*it] );
}
if (C[ *it ] + d[nod] < d[ B[*it] ])
{
d[ B[*it] ] = C[ *it ] + d[nod];
heap_update( B[*it] );
}
}
}
for (i=1;i<=K;++i)
dist[nrd][s][i]=d[det[i]];
}
void compute()
{
int i,j;
//gigel catre primu detinut
det[0]=1;
dijkstra(0,0);
//drumuri intre detinuti
for (i=1;i<=K;++i)
for (j=1;j<=K;++j)
dijkstra(i,j);
}
void dinamica()
{
int i,j,k,P[Kmax],nrd,min=infinit;
P[0]=1;
for (i=1;i<=K;++i)
P[i]=P[i-1]<<1;
for (i=1;i<=K;++i)
a[P[i-1]][i]=dist[0][0][i]+1;
for (i=1;i<P[K];++i)
{
nrd=0;
for (j=0;j<K;++j)
if (i&P[j]) ++nrd;
for (j=1;j<=K;++j)
if (i&P[j-1])
for (k=1;k<=K;++k)
if ((i&P[k-1])&&(k!=j))
if ((a[i][j]==0)||(a[i][j]>a[i-P[j-1]][k]+nrd*dist[nrd-1][k][j]))
a[i][j]=a[i-P[j-1]][k]+nrd*dist[nrd-1][k][j];
}
for (i=1;i<=K;++i)
if (a[P[K]-1][i]<min) min=a[P[K]-1][i];
freopen("gather.out","w",stdout);
printf("%d",min-1);
fclose(stdout);
}
int main()
{
citire();
compute();
dinamica();
return 0;
}