Pagini recente » Cod sursa (job #3193156) | Cod sursa (job #3163221) | Cod sursa (job #2177267) | Cod sursa (job #2847180) | Cod sursa (job #2975187)
#include <bits/stdc++.h>
using namespace std;
const int NMAX = 754;
const int KMAX = 15;
ifstream fin("gather.in");
ofstream fout("gather.out");
int n, m, k;
int pers[KMAX + 4];
struct edge
{
int u;
int c;
int p;
};
vector<edge> adj[NMAX];
int dp[KMAX + 4][(1 << KMAX) + 4];
int d[KMAX + 4][KMAX + 4][KMAX + 4];
int d1[NMAX];
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> Q;
int rez = INT_MAX;
void dijkstra(int s, int max_p)
{
int dist[NMAX];
for (int i = 1; i <= n; i++)
{
dist[i] = INT_MAX;
}
dist[pers[s]] = 0;
Q.push({0, pers[s]});
while (!Q.empty())
{
int v = Q.top().second;
int d_v = Q.top().first;
Q.pop();
if (d_v != dist[v])
{
continue;
}
for (auto e : adj[v])
{
int u = e.u;
int cost = e.c;
int p = e.p;
if (dist[v] + cost < dist[u] && max_p <= p)
{
dist[u] = dist[v] + cost;
Q.push({dist[u], u});
}
}
}
for (int i = 1; i <= k; i++)
{
d[s][i][max_p] = dist[pers[i]];
}
}
void dijkstra1()
{
for (int i = 1; i <= n; i++)
{
d1[i] = INT_MAX;
}
d1[1] = 0;
Q.push({0, 1});
while (!Q.empty())
{
int v = Q.top().second;
int d_v = Q.top().first;
Q.pop();
if (d_v != d1[v])
{
continue;
}
for (auto e : adj[v])
{
int u = e.u;
int cost = e.c;
if (d1[v] + cost < d1[u])
{
d1[u] = d1[v] + cost;
Q.push({d1[u], u});
}
}
}
}
int main()
{
fin >> k >> n >> m;
for (int i = 1; i <= k; i++)
{
fin >> pers[i];
}
for (int i = 1; i <= m; i++)
{
int a, b, c, d;
fin >> a >> b >> c >> d;
adj[a].push_back({b, c, d});
adj[b].push_back({a, c, d});
}
dijkstra1();
for (int i = 1; i <= k; i++)
{
for (int j = 1; j <= k; j++)
{
dijkstra(i, j);
}
}
for (int i = 1; i <= k; i++)
{
for (int conf = 0; conf < (1 << k); conf++)
{
dp[i][conf] = INT_MAX;
}
}
for (int i = 1; i <= k; i++)
{
dp[i][1 << (i - 1)] = d1[pers[i]];
}
for (int conf = 1; conf < (1 << k); conf++)
{
for (int i = 1; i <= k; i++)
{
if (conf & (1 << (i - 1)))
{
for (int j = 1; j <= k; j++)
{
if (i == j)
{
continue;
}
if (conf & (1 << (j - 1)))
{
int p = __builtin_popcount(conf);
if (d[i][j][p] < INT_MAX)
{
dp[j][conf] = min(dp[j][conf], dp[i][conf ^ (1 << (j - 1))] + p * d[i][j][p - 1]);
}
}
}
}
}
}
// for (int i = 1; i <= k; i++)
// {
// for (int conf = 1; conf < (1 << k); conf++)
// {
// cout << conf << ' ' << dp[i][conf] << ' ';
// }
// cout << '\n';
// }
for (int i = 1; i <= k; i++)
{
rez = min(rez, dp[i][(1 << k) - 1]);
}
fout << rez;
fin.close();
fout.close();
return 0;
}