Pagini recente » Cod sursa (job #741330) | Diferente pentru blog/viata-dupa-olimpiade-1 intre reviziile 26 si 27 | Istoria paginii autumn-warmup-2007/solutii/runda-3 | Cod sursa (job #584792) | Cod sursa (job #2011076)
#include<bits/stdc++.h>
#define maxN 2005
#define maxK 20
#define INF 2000000000000000LL
using namespace std;
int n,c[maxN];
vector<pair<int,int> > v[maxN];
long long dp[(1<<17)+5][maxK];
long long dist[maxK][maxN];
int m,k,x,y,z;
typedef struct edge
{
int nod;
long long cost;
bool operator<(const edge& other) const
{
return cost>other.cost;
}
};
priority_queue<edge> q;
inline void RunDijkstra(int pos)
{
for(int j=1;j<=n;j++)
{
dist[pos][j]=INF;
q.push({j,INF});
}
dist[pos][c[pos]]=0;
q.push({c[pos],0});
while(!q.empty())
{
int nod=q.top().nod;
long long cost=q.top().cost;
q.pop();
if(cost>dist[pos][nod]) continue;
for(vector<pair<int,int> >::iterator it=v[nod].begin();it!=v[nod].end();it++)
{
if((cost+it->second)<dist[pos][it->first])
{
dist[pos][it->first]=cost+1LL*it->second;
q.push({it->first,dist[pos][it->first]});
}
}
}
}
int main()
{
freopen("ubuntzei.in","r",stdin);
freopen("ubuntzei.out","w",stdout);
scanf("%d%d",&n,&m);
scanf("%d",&k);
for(int i=1;i<=k;i++)
{
scanf("%d",&c[i]);
}
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&x,&y,&z);
v[x].push_back({y,z});
v[y].push_back({x,z});
}
c[0]=1;
c[++k]=n;
for(int mask=1;mask<=(1<<(k+1))-1;mask++)
for(int i=0;i<=k;i++)
dp[mask][i]=INF;
dp[1][0]=0;
for(int i=0;i<=k;i++)
{
RunDijkstra(i);
}
int lmask=(1<<(k+1))-1;
for(int mask=1;mask<=lmask;mask++)
{
for(int i=0;i<=k;i++)
{
if(dp[mask][i]==INF) continue;
if(!((1<<i)&mask)) continue;
for(int j=0;j<=k;j++)
{
if((1<<j)&mask) continue;
dp[mask+(1<<j)][j]=min(dp[mask+(1<<j)][j],dp[mask][i]+1LL*dist[i][c[j]]);
}
}
}
printf("%lld\n",dp[lmask][k]);
return 0;
}