Pagini recente » Cod sursa (job #678551) | Cod sursa (job #676771)
Cod sursa(job #676771)
/*
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 N;
int st[20];
int best,sum;
int F[20];
struct{
int x,y,c;
}nod[10005];
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<=m;i++)
scanf("%d%d%d",&nod[i].x,&nod[i].y,&nod[i].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<=n; i++)
D[i] = inf;
for(int i=1; i<=m; i++){ // Copiez linia A[start] in D
if(nod[i].x == start)
D[nod[i].y] = nod[i].c;
if(nod[i].y == start)
D[nod[i].x] = nod[i].c;
}
/* 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<=m; j++){
if(nod[j].x == poz) // Daca sunt pe linia A[poz]
if(min + nod[j].c < D[nod[j].y] && !S[nod[j].y])
D[nod[j].y] = min + nod[j].c;
if(nod[j].y == poz)
if(min + nod[j].c < D[nod[j].x] && !S[nod[j].x])
D[nod[j].x] = min + nod[j].c;
}
}
++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;
}