Pagini recente » Cod sursa (job #2970530) | Cod sursa (job #777842) | Cod sursa (job #2983295) | Cod sursa (job #2103615) | Cod sursa (job #3242053)
#include <fstream>
#include <bits/stdc++.h>
using namespace std;
ifstream fin("ubuntzei.in");
ofstream fout("ubuntzei.out");
int n, m, k, v[2005], i, j, dp[2005][1<<17], cost[2005][2005], dist[2005], x, y, z, mask, ans=1e9+1;
vector <pair<int, int>> gr[2005];
//dp[i][mask] lantul de cost minim care incepe din nodul 1 si se termina in nodul j
//si care trece prin nodurile reprezentate de bitul 1 din configuratia binara a lui mask
void dijkstra(int val)
{
set <pair <int,int>>q;
q.insert({0, val});
for(int i=0; i<n; i++)
dist[i]=2e9;
dist[val]=0;
while(!q.empty())
{
int nod=q.begin()->second;
q.erase(q.begin());
for(vector<pair<int, int>>::iterator it=gr[nod].begin(); it!=gr[nod].end(); it++)
{
int cost=it->first;
int y=it->second;
if(dist[y]>dist[nod]+cost)
{
if(dist[y]!=2e9)
q.erase(q.find({dist[y], y}));
dist[y]=dist[nod]+cost;
q.insert({dist[y], y});
}
}
}
for(int i=0; i<n; i++)
cost[val][i]=dist[i]; //costul minim de a ajunge de la un nod de interes (0, c1, c2,..ck, n-1) la celelalte noduri
}
int main()
{
fin>>n>>m>>k;
for(i=0; i<k+2; i++)
for(j=0; j<k+2; j++)
cost[i][j]=1e9;
//notez nodurile 0, c1, c2, ..., ck, n-1 cu 0, 1, 2, ...,k+1
for(i=1; i<=k; i++)
{
fin>>v[i];
v[i]--;
}
v[0]=0;
v[k+1]=n-1;
for(i=1; i<=m; i++)
{
fin>>x>>y>>z;
x--;
y--;
gr[x].push_back({z, y});
gr[y].push_back({z, x});
}
dijkstra(0);
dijkstra(n-1);
for(i=1; i<=k; i++)
dijkstra(v[i]);
k+=2;
for(int i=0; i<k; i++)
for(int mask=0; mask<(1<<k); mask++)
dp[i][mask]=1e9;
for(i=0; i<k; i++)
dp[i][(1<<i)]=cost[v[i]][0];
for(int mask=1; mask<(1<<k); mask++)
for(int i=0; i<k; i++)
if(mask&(1<<i)) //nodul i se afla in configuratia binara a lui mask
for(int j=0; j<k; j++)
if(mask&(1<<j)) //nodul j se afla in configuratia binara a lui mask
dp[i][mask]=min(dp[i][mask], dp[j][mask-(1<<i)]+cost[v[j]][v[i]]);
fout<<dp[k-1][(1<<k)-1];
return 0;
}