Pagini recente » Cod sursa (job #3185325) | Cod sursa (job #2177281) | Cod sursa (job #3274049) | Cod sursa (job #3293102) | Cod sursa (job #2927477)
/// Preset de infoarena
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <algorithm>
#include <bitset>
using namespace std;
#define int long long
ifstream fin("gather.in");
ofstream fout("gather.out");
const int maxN = 755, maxK = 17, inf = 0x3f3f3f3f;
int n, k, m, v[maxK], dist[maxK][maxK][maxN], dp[maxK][(1 << maxK)];
bool used[maxN];
struct mucie {
int nod, c, cap;
};
vector <mucie> G[maxN];
priority_queue <pair<int, int>> heap;
void dijkstra(int start, int nrp)
{
for(int i = 1; i <= n; i++)
dist[start][nrp][i] = inf, used[i] = 0;
heap.push({0, v[start]});
dist[start][nrp][v[start]] = 0;
while(!heap.empty())
{
auto curr = heap.top();
int nod = curr.second, cost = -curr.first;
heap.pop();
if(used[curr.second])
continue;
used[curr.second] = 1;
for(auto nxt : G[curr.second])
{
if(nxt.cap < nrp)
continue;
if(cost + nxt.c < dist[start][nrp][nxt.nod])
{
dist[start][nrp][nxt.nod] = cost + nxt.c;
heap.push({-dist[start][nrp][nxt.nod], nxt.nod});
}
}
}
}
signed main()
{
fin >> k >> n >> m;
for(int i = 1; i <= k; i++)
fin >> v[i];
sort(v + 1, v + k + 1);
for(int i = 1; i <= m; i++)
{
int x, y, c, cc;
fin >> x >> y >> c >> cc;
G[x].push_back({y, c, cc});
G[y].push_back({x, c, cc});
}
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 j = 1; j <= k; j++)
// {
// fout << "Nodul de start este " << i << " si numarul de prizonieri e " << j << '\n';
// for(int ii = 1; ii <= n; ii++)
// fout << dist[i][j][ii] << ' ';
// fout << '\n';
// }
// }
for(int i = 0; i < k; i++)
for(int c = 0; c < (1 << k); c++)
dp[i][c] = inf;
for(int i = 0; i < k; i++)
dp[i][(1 << i)] = dist[i + 1][1][1];
for(int c = 0; c < (1 << k); c++)
{
for(int nod = 0; nod < k; nod++)
{
if((c & (1 << nod)) == 0)
continue;
for(int vecin = 0; vecin < k; vecin++)
{
if(vecin == nod || (c & (1 << vecin)))
continue;
int nrp = __builtin_popcount(c);
dp[vecin][c ^ (1 << vecin)] = min(dp[vecin][c ^ (1 << vecin)], dp[nod][c] + (nrp + 1) * dist[nod + 1][nrp][v[vecin + 1]]);
}
}
}
int ans = inf;
for(int i = 0; i < k; i++)
ans = min(ans, dp[i][(1 << k) - 1]);
fout << ans;
return 0;
}