Pagini recente » Cod sursa (job #2165746) | Cod sursa (job #168361) | Cod sursa (job #2093013) | Cod sursa (job #1580659) | Cod sursa (job #1621786)
#include <fstream>
#include <vector>
#include <queue>
#include <algorithm>
#include <iostream>
using namespace std;
const int INF = 0x3f3f3f3f;
priority_queue< pair<int, int> > pq;
queue<pair <int, int> > q;
vector<int> g[2002];
vector<int> cost[2002];
int d[17][2002];
int friends[20];
int df[20][20];
bool vis[17][2002];
int config1[17][131075], config2[17][131075];
bool inq1[17][131075], inq2[17][131075];
int nr[131075];
int main()
{
ifstream in("ubuntzei.in");
ofstream out("ubuntzei.out");
int n, m;
in >> n >> m;
int k;
in >> k;
friends[0] = 1;
for (int i = 1; i <= k; i++)
in >> friends[i];
friends[k+1] = n;
for (int i = 1, x, y, c; i <= m; i++)
{
in >> x >> y >> c;
g[x].push_back(y);
g[y].push_back(x);
cost[x].push_back(c);
cost[y].push_back(c);
}
for (int start = 0; start <= k+1; start++)
{
for (int i = 1; i <= n; i++)
d[start][i] = INF;
d[start][friends[start]] = 0;
pq.push(make_pair(0, friends[start]));
while (!pq.empty())
{
int node = pq.top().second;
pq.pop();
if (vis[start][node])
continue;
vis[start][node] = true;
for (int i = 0; i < g[node].size(); i++)
if (d[start][g[node][i]] > d[start][node] + cost[node][i])
{
d[start][g[node][i]] = d[start][node] + cost[node][i];
pq.push(make_pair(-d[start][g[node][i]], g[node][i]));
}
}
}
for (int i = 0; i <= k+1; i++)
{
for (int j = 0; j <= k+1; j++)
{
df[i][j] = d[i][friends[j]];
//out << df[i][j] << ' ';
}
//out << '\n';
}
if (k == 0)
{
out << df[0][1] << '\n';
return 0;
}
k++;
int invert = (1<<(k+1))-1;
if ((k+1)/2 > 1)
q.push(make_pair(k, 1<<k));
config2[k][1<<k] = 1;
nr[1<<k] = 1;
inq2[k][1<<k] = true;
while (!q.empty())
{
int first = q.front().first;
int config = q.front().second;
q.pop();
for (int i = 1; i < k; i++)
if (!(config & (1<<i)))
{
int nc = config | (1<<i);
if (config2[i][nc] > config2[first][config] + df[i][first] || config2[i][nc] == 0)
{
config2[i][nc] = config2[first][config] + df[i][first];
nr[nc] = nr[config] + 1;
if (nr[nc] < (k+1)/2 && !inq2[i][nc])
{
q.push(make_pair(i, nc));
inq2[i][nc] = true;
}
}
}
}
int sol = INF;
q.push(make_pair(0, 1));
config1[0][1] = 0;
nr[1] = 1;
inq1[0][1] = true;
while (!q.empty())
{
int last = q.front().first;
int config = q.front().second;
q.pop();
for (int i = 1; i < k; i++)
if (!(config & (1<<i)))
{
int nc = config | (1<<i);
if (config1[i][nc] > config1[last][config] + df[last][i] || config1[i][nc] == 0)
{
config1[i][nc] = config1[last][config] + df[last][i];
nr[nc] = nr[config] + 1;
if (nr[nc] < k/2+1 && !inq1[i][nc])
{
q.push(make_pair(i, nc));
inq1[i][nc] = true;
}
else if (nr[nc] == k/2+1)
{
//out << i << ' ' << nc << '\n';
inq1[i][nc] = true;
for (int j = 1; j <= k; j++)
if (!(nc & (1<<j)))
{
//out << j << ' ' << (nc ^ invert) << '\n' << config1[i][nc] << ' ' << config2[j][nc ^ invert] - 1 << ' ' << df[i][j] << '\n';
if (config2[j][nc ^ invert])
sol = min(sol, config1[i][nc] + config2[j][nc ^ invert] + df[i][j] - 1);
}
//out << '\n';
}
}
}
}
out << sol << '\n';
return 0;
}