Pagini recente » Cod sursa (job #1065066) | Cod sursa (job #2790482) | Cod sursa (job #1325244) | Cod sursa (job #1154265) | Cod sursa (job #115539)
Cod sursa(job #115539)
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;
int a[Kmax][Pmax];
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;
}
}
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[f]<d[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;
p[0]=1;
for (i=1;i<=K;++i)
p[i]=p[i-1]<<1;
for (i=1;i<=K;++i)
a[1][p[i-1]]=dist[0][0][i]+1;
for (i=3;i<p[K];++i)
{
nrd=0;
for (j=0;j<K;++j)
if (i&p[j]) ++nrd;
if (nrd==1) continue;
for (j=0;j<K;++j)
if (i&p[j])
for (k=0;k<K;++k)
if ((k!=j)&&(i&p[k])&&((a[nrd][i]==0)||(a[i][nrd]>a[nrd-1][i-p[j]]+nrd*dist[nrd-1][k+1][j+1])))
a[nrd][i]=a[nrd-1][i-p[j]]+nrd*dist[nrd-1][k+1][j+1];
}
freopen("gather.out","w",stdout);
printf("%d",a[K][p[K]-1]-1);
fclose(stdout);
}
int main()
{
citire();
compute();
dinamica();
return 0;
}