Pagini recente » Cod sursa (job #583515) | Cod sursa (job #2116223) | Cod sursa (job #3198948) | Cod sursa (job #1109559) | Cod sursa (job #2942652)
#include<fstream>
#include<vector>
#include<queue>
#include<cstring>
using namespace std;
ifstream cin("ubuntzei.in");
ofstream cout("ubuntzei.out");
const int NMAX = 2000;
const int INF = 1e9;
vector<pair<int, int>> v[NMAX+1], v2[16]; /// vecin, cost
vector<int> city;
int dp[19][1<<19], v1[17][17], ct[NMAX+1];
int n;
void dijkstra(int nr, int pos)
{
priority_queue<pair<int, int>> pq; ///cost, vecin
bool viz[NMAX+1];
memset(viz, 0, sizeof(viz));
for(int i=1; i<=n; i++)
ct[i] = INF;
pq.push({0, nr});
ct[nr] = 0;
while(!pq.empty())
{
pair<int, int> elem = pq.top();
pq.pop();
int nod = elem.second;
int cost = -elem.first;
if(!viz[nod])
{
viz[nod] = 1;
for(int i=0; i<city.size(); i++)
{
if(city[i] == nod)
{
v2[pos+1].push_back({i+1, cost});
v1[pos+1][i+1] = cost;
}
}
if(nod == 1)
{
v2[pos+1].push_back({0, cost});
v2[0].push_back({pos+1, cost});
v1[0][pos+1] = cost;
v1[pos+1][0] = cost;
}
if(nod == n)
{
//v2[nr].push_back({n, cost});
v1[16][pos+1] = cost;
v1[pos+1][16] = cost;
}
for(auto elem2: v[nod])
{
int vecin = elem2.first;
int pret = elem2.second;
if(!viz[vecin] && ct[vecin] > ct[nod]+pret)
{
ct[vecin] = ct[nod]+pret;
pq.push({-(ct[nod]+pret), vecin});
}
}
}
}
}
int main()
{
int m, k;
cin>>n>>m>>k;
for(int i=1; i<=k; i++)
{
int x;
cin>>x;
city.push_back(x);
}
for(int i=1; i<=m; i++)
{
int x, y, c;
cin>>x>>y>>c;
v[x].push_back({y, c});
v[y].push_back({x, c});
}
for(int i=0; i<17; i++)
for(int j=0; j<=17; j++)
v1[i][j] = 0;
for(int i=0; i<city.size(); i++)
dijkstra(city[i], i);
for(int mask=1; mask < 1<<16; mask++)
for(int nod=0; nod <= k; nod++)
dp[nod][mask] = INF;
dp[0][1] = 0;
int minim = INF;
for(int mask=1; mask < 1<<16; mask++)
for(int nod=0; nod <= k; nod++)
if(dp[nod][mask] != INF)
{
//cout<<nod<<" "<<mask<<" "<<dp[nod][mask]<<'\n';
if(mask == (1<<(k+1))-1 && v1[nod][16])
minim = min(minim, dp[nod][mask] + v1[nod][16]);
for(auto x : v2[nod])
{
int vecin = x.first;
int cost = x.second;
if(!(mask & (1<<vecin)))
{
dp[vecin][mask ^ (1<<vecin)] = min(dp[vecin][mask ^ (1<<vecin)], dp[nod][mask] + cost);
}
}
}
cout<<minim;
return 0;
}