Pagini recente » Cod sursa (job #1160801) | Cod sursa (job #2361948) | Cod sursa (job #1379528) | Cod sursa (job #2218327) | Cod sursa (job #677396)
Cod sursa(job #677396)
/*
Dijkstra din toate nodurile
K[i] + nodul 1.
*/
#include<cstdio>
#include<cstring>
#include<climits>
#include<algorithm>
#define inf 2005
#define inf2 100000005
int n,m,k;
int K[inf];
int S[inf], D[inf];
int B[20][inf];
int A[inf][inf];
int N;
int st[20];
int best,sum;
int F[20];
void read(){
freopen("ubuntzei.in","r",stdin);
scanf("%d%d",&n,&m);
scanf("%d",&k);
for(int i=1;i<=k;i++)
scanf("%d",&K[i]);
for(int i=1;i<=n;i++)
for(int j=i+1; j<=n; j++)
A[i][j]=inf;
int x,y,c;
for(int i=1;i<=m;i++){
scanf("%d%d%d",&x,&y,&c);
if(x<y)
A[x][y]=c;
else
A[y][x]=c;
}
fclose(stdin);
}
void dijkstra(int start){
//memset(S,0,4*(n+1));
/* Initializare Dijkstra */
/*S[start]++; // Selectez nodul start;
for(int i=1; i<=start; i++){ // Copiez linia A[start] in D
D[i]=A[i][start];
}
for(int i=start; i<=n; i++){
D[i]=A[start][i];
}*/
/* Dijkstra */
for(int i=1; i<=n-2; i++){
// Caut minimul din D[i] cu !S[i]
int min = inf;
int poz;
for(int j=1; j<=n; j++)
if(D[j] < min && !S[j]){
min=D[j];
poz=j;
}
// Selectez nodul poz
S[poz]++;
// Caut prin nodul poz drumuri mai scurte catre toate
// nodurile neselectate pana acum
for(int j=1; j<=n; j++){
if(min + A[poz][j] < D[j] && A[poz][j])
D[j]=min + A[poz][j];
if(min + A[j][poz] < D[j] && A[j][poz])
D[j]=min + A[j][poz];
}
}
++N;
int j=0;
for(int i=1;i<=n;i++)
if(std::binary_search(K+1,K+k+1,i) || i==1 || i==n)
B[N][++j]=D[i];
}
void back(int k){
for(int i=2;i<=N;i++){
if(!F[i]){ // Daca nu am mai trecut inca o data prin nodul i
st[k] = i; // Adaug un element la drum;
sum += B[st[k-1]][st[k]]; // Adaug costul la suma;
F[i] ++; // Marchez ca am trecut prin nodul i
if(k==N){
if(sum + B[st[N]][k+1] < best) best = sum + B[st[N]][k+1];
}
else if(sum <= best)
back(k+1);
sum -= B[st[k-1]][st[k]];
F[i] --;
}
}
}
int main(){
read();
std::sort(K+1,K+1+k);
dijkstra(1);
for(int i=1;i<=k;i++)
dijkstra(K[i]);
freopen("ubuntzei.out","w",stdout);
if(!k) printf("%d",B[1][2]);
else{
/* Initializare back */
st[1] = 1;
F[1] ++;
best = INT_MAX;
back(2);
printf("%d",best);
}
fclose(stdout);
return 0;
}