Pagini recente » Cod sursa (job #3344716) | Cod sursa (job #990298) | Cod sursa (job #776265) | Cod sursa (job #1440969) | Cod sursa (job #3339276)
#include <fstream>
#include <vector>
#include <queue>
using namespace std;
ifstream cin("gather.in");
ofstream cout("gather.out");
const int Nmax = 755, Kmax = 15;
struct muchie
{
int y, dist, cnt;
};
vector<muchie>g[Nmax];
struct stare
{
int nod, mask, dist;
bool operator>(const stare &x ) const
{
if(dist != x.dist)
return dist > x.dist;
if(mask != x.mask) return mask > x.mask;
return nod > x.nod;
}
};
int dist[Nmax][(1<<Kmax)];
bool det[Nmax];
int idx[Nmax];
int n, k;
void dijk()
{
for(int i = 1; i <= n; i ++)
for(int mask = 0; mask < (1 << k); mask ++)
dist[i][mask] = 1e9;
dist[1][0] = 0;
priority_queue<stare, vector<stare>, greater<stare>> pq;
pq.push({1, 0, 0});
while(!pq.empty())
{
stare now = pq.top();
pq.pop();
//cout << now.nod << " " << now.dist << " " << now.mask << '\n';
int x = now.nod, mask = now.mask, distc = now.dist;
int nrb = __builtin_popcount(mask) + 1;
for(auto it: g[x])
{
int y = it.y, distm = it.dist, cnt = it.cnt;
if(det[y] == 1)
{
//cout << "aaa " << y << '\n';
int mask2 = mask | (1 << idx[y]);
if(nrb - 1 <= cnt && distc + distm * nrb < dist[y][mask2])
{
dist[y][mask2] = distc + distm * nrb;
pq.push({y, mask2, dist[y][mask2]});
}
}
else
{
if(nrb - 1 <= cnt && distc + distm * nrb < dist[y][mask])
{
dist[y][mask] = distc + distm * nrb;
pq.push({y, mask, dist[y][mask]});
}
}
}
}
}
int main()
{
int m, x, y, c, d;
cin >> k >> n >> m;
for(int i = 1; i <= k; i ++)
{
cin >> x;
det[x] = 1;
idx[x] = i - 1;
}
for(int i = 1; i <= m; i ++)
{
cin >> x >> y >> c >> d;
g[x].push_back({y, c, d});
g[y].push_back({x, c, d});
}
dijk();
int ans = 1e9, mask = (1 << k) - 1;
for(int i = 1; i <= n; i ++)
ans = min(ans, dist[i][mask]);
cout << ans;
return 0;
}