Pagini recente » Cod sursa (job #3271804) | Cod sursa (job #2352737) | Cod sursa (job #2319188) | Cod sursa (job #2352727) | Cod sursa (job #891573)
Cod sursa(job #891573)
#include<cstdio>
#include<vector>
#include<algorithm>
#include<cstring>
using namespace std;
#define pp pair<int,int>
#define ff first
#define ss second
#define MAXK 19
#define MAXN 2001
#define MAXS 1<<16
#define inf 2000000000
vector < pp > v[MAXN];
int loc[MAXK],DP[MAXK][MAXS],drum[MAXK][MAXK];
int H[MAXN],poz[MAXN],d[MAXN];
int N,M,K,hp;
void build_heap(int nod){
int i;
for(i=1;i<=hp;i++)
H[i]=poz[i]=i;
if(nod!=1){
swap(poz[nod],poz[1]);
swap(H[nod],H[1]);
}
}
void sift(int p){
int son;
do{
son=0;
if(2*p<=hp)
son=2*p;
if(son+1<=hp && d[H[son+1]]<d[H[son]])
son++;
if(d[H[son]]>d[H[p]])
son=0;
if(son){
swap(poz[H[p]],poz[H[son]]);
swap(H[p],H[son]);
p=son;
}
}while(son);
}
void percolate(int p){
while(p>1 && d[H[p]]<d[H[p/2]]){
swap(poz[H[p]],poz[H[p/2]]);
swap(H[p],H[p/2]);
p/=2;
}
}
int Min(){
int key;
key=H[1];
swap(poz[H[1]],poz[H[hp]]);
H[1]=H[hp--];
sift(1);
return key;
}
void Dijkstra(int p){
pp aux;
int i,j,vfmin,dmin;
for(i=1;i<=N;i++)
d[i]=inf;
d[loc[p]]=0;hp=N;
build_heap(loc[p]);
for(i=1;i<=N;i++){
vfmin=Min();
dmin=d[vfmin];
for(j=0;j<(int)v[vfmin].size();j++){
aux=v[vfmin][j];
if(dmin+aux.ss<d[aux.ff]){
d[aux.ff]=dmin+aux.ss;
percolate(poz[aux.ff]);
}
}
}
for(j=0;j<K;++j)
drum[p][j]=d[loc[j]];
}
int main(){
int x,y,c,i,j,t,jnou;
freopen("ubuntzei.in","r",stdin);
scanf("%d%d",&N,&M);
scanf("%d",&K);
for(i=0;i<K;++i)
scanf("%d",&loc[i]);
loc[K++]=1;loc[K++]=N;
sort(loc,loc+K);
for(i=1;i<=M;i++){
scanf("%d%d%d",&x,&y,&c);
v[x].push_back(make_pair(y,c));
v[y].push_back(make_pair(x,c));
}
fclose(stdin);
for(i=0;i<K;++i)
Dijkstra(i);
for(i=0;i<MAXK;++i)
for(j=0;j<MAXS;++j)
DP[i][j]=inf;
DP[0][1]=0;
for(j=0;j<(1<<K)-1;++j){
for(i=0;i<K;++i){
if(DP[i][j]!=inf){
for(t=0;t<K;++t)
if((j & (1<<t))==0){
jnou=j+(1<<t);
if(DP[t][jnou]>DP[i][j]+drum[i][t])
DP[t][jnou]=DP[i][j]+drum[i][t];
}
}
}
}
freopen("ubuntzei.out","w",stdout);
printf("%d\n",DP[K-1][(1<<K)-1]);
fclose(stdout);
return 0;
}