Pagini recente » Cod sursa (job #189325) | Cod sursa (job #1850786) | Cod sursa (job #1185496) | Cod sursa (job #879369) | Cod sursa (job #2126997)
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
using namespace std;
const int INF = 50000000;
struct prieten
{
int id;
int distStart, distStop;
vector<int> dist; //dist[i] = distanta pana la prietenul i
};
void GetDist(vector<int> &ret, vector<vector<pair<int, int> > > &vecini, int start)
{
fill(ret.begin(), ret.end(), INF);
priority_queue<pair<int, int>, vector<pair<int, int> >, greater<pair<int, int> > > q;
q.push(make_pair(0, start));
vector<bool> viz(ret.size(), false);
pair<int, int> p;
ret[start] = 0;
while(q.empty() == false)
{
p = q.top();
q.pop();
if(viz[p.second])
continue;
viz[p.second] = true;
for(auto v:vecini[p.second])
if(ret[v.second] > p.first + v.first)
{
ret[v.second] = p.first + v.first;
q.push(make_pair(ret[v.second], v.second));
}
}
}
int main()
{
ifstream in("ubuntzei.in");
int n, m, k;
in >> n >> m;
in >> k;
vector<prieten> prieteni(k);
for(int i = 0; i < k; ++i)
in >> prieteni[i].id;
vector<vector<pair<int, int> > > vecini(n + 1); //.first = cost, .second = vecin
int x, y, z;
while(m--)
{
in >> x >> y >> z;
vecini[x].push_back(make_pair(z, y));
vecini[y].push_back(make_pair(z, x));
}
in.close();
vector<int> dist(n + 1);
for(auto &p:prieteni)
{
p.dist.resize(prieteni.size());
GetDist(dist, vecini, p.id);
p.distStart = dist[1];
p.distStop = dist[n];
for(int i = 0; i < prieteni.size(); ++i)
p.dist[i] = dist[prieteni[i].id];
}
int rasp;
if(prieteni.size() == 0)
{
GetDist(dist, vecini, 1);
rasp = dist[n];
}
else if(prieteni.size() == 1)
rasp = prieteni[0].distStart + prieteni[0].distStop;
else
{
rasp = INF;
int i = 0;
vector<vector<int> > dp(1 << (prieteni.size() + 1), vector<int>(prieteni.size(), INF));
dp[1 << i][i] = 0;
for(int j = 0; j < (1 << prieteni.size()); ++j)
{
if((j & (1 << i)) == 0)
continue;
for(int k = 0; k < prieteni.size(); ++k)
{
if((j & (1 << k)) == 0)
continue;
for(int t = 0; t < prieteni.size(); ++t)
{
if((j & (1 << t)) == 0)
continue;
dp[j][k] = min(dp[j][k], dp[j - (1 << k)][t] + prieteni[k].dist[t]);
}
}
}
for(int j = 0; j < prieteni.size(); ++j)
{
if(j == i)
continue;
int all = (1 << prieteni.size()) - 1 - (1 << j);
for(int t = 0; t < prieteni.size(); ++t)
rasp = min(rasp, prieteni[i].distStart + dp[all][t] + prieteni[j].dist[t] + prieteni[j].distStop);
}
}
ofstream out("ubuntzei.out");
out << rasp;
out.close();
return 0;
}