Pagini recente » Cod sursa (job #2708057) | Cod sursa (job #1448237) | Cod sursa (job #1417444) | Cod sursa (job #1379446) | Cod sursa (job #1913539)
#include <stdio.h>
#include <vector>
#include <queue>
using namespace std;
#define INF 2000000
#define MAXN 2011
FILE *fin=fopen("ubuntzei.in","r");
FILE *fout = fopen("ubuntzei.out","w");
int best[MAXN][MAXN];
int vizitat[MAXN];
int cnt[MAXN];
int bit(int i,int j)
{
return i&(1<<j);
}
int trebuie[MAXN];
int drum[MAXN][34000];
struct pereche
{
int muc;
int cost;
};
vector <pereche> muchie[MAXN];
int main()
{
int n,m,k;
fscanf(fin,"%d%d%d",&n,&m,&k);
for(int j=0;j<k;j++)
{
fscanf(fin,"%d",&trebuie[j]);
}
for(int j=0;j<m;j++)
{
int x,y,z;
fscanf(fin,"%d%d%d",&x,&y,&z);
muchie[y].push_back(pereche{x,z});
muchie[x].push_back(pereche{y,z});
}
trebuie[k]=1;
for(int i=0;i<=k;i++)
for(int j=1;j<=n;j++)
{
if(j!=trebuie[i])
{
best[trebuie[i]][j]=INF;
}
}
for(int i=0;i<=k;i++)
{
for(int j=1;j<=n;j++)
{
vizitat[j]=0;
cnt[j]=0;
}
queue <int> frontiera;
cnt[trebuie[i]]=1;
int ok=1;
vizitat[trebuie[i]]=1;
frontiera.push(trebuie[i]);
while(!frontiera.empty() && ok==1)
{
int nod=frontiera.front();
//fprintf(stderr, "%d: ", nod);
vizitat[nod]=0;
frontiera.pop();
for(pereche node:muchie[nod])
{
if(best[trebuie[i]][nod] + node.cost < best[trebuie[i]][node.muc])
{
best[trebuie[i]][node.muc]=best[trebuie[i]][nod] + node.cost;
if(vizitat[node.muc]==0)
{
cnt[node.muc]++;
vizitat[node.muc]=1;
if(cnt[node.muc]>n)ok=0;
frontiera.push(node.muc);
//fprintf(stderr, "%d ", node.muc);
}
}
}
//fprintf(stderr, "\n");
}
//fprintf(stderr, "\n");
}
/*
for(int i = 1; i <= n; i++) {
fprintf(stderr, "%d ", best[1][i]);
}
fprintf(stderr, "\n");
for(int i = 1; i <= n; i++) {
fprintf(stderr, "%d ", best[2][i]);
}
fprintf(stderr, "\n");//*/
for(int i=0;i<k;i++)
{
for(int j=0;j<1<<k;j++)
{
drum[trebuie[i]][j]=INF;
}
}
for(int i=0;i<k;i++)
{
drum[trebuie[i]][1<<i]=best[trebuie[i]][1];
}
for(int i=1;i<(1<<k);i++)
{
for(int j=0;j<k;j++)
{
if(bit(i,j))
{
for(int q=0;q<k;q++)
{
if(q!=j && bit(i,q))
{
if(drum[trebuie[j]][i]>drum[trebuie[q]][i-(1<<j)]+best[trebuie[q]][trebuie[j]])
drum[trebuie[j]][i]=drum[trebuie[q]][i-(1<<j)]+best[trebuie[q]][trebuie[j]];
}
}
}
}
}
int minim=INF;
minim=drum[trebuie[0]][(1<<k)-1]+best[trebuie[0]][n];
for(int i=0;i<k;i++)
{
if(minim>best[trebuie[i]][n]+drum[trebuie[i]][(1<<k)-1])
minim=best[trebuie[i]][n]+drum[trebuie[i]][(1<<k)-1];
}
if(k!=0)fprintf(fout,"%d",minim);
else fprintf(fout,"%d",best[1][n]);
return 0;
}