Pagini recente » Cod sursa (job #2892634) | Cod sursa (job #23366) | Cod sursa (job #1526317) | Cod sursa (job #446170) | Cod sursa (job #2650048)
#include <bits/stdc++.h>
#define point pair<int, int>
#define dist first
#define nod second
#define oo 1e10
using namespace std;
ifstream fin("gather.in");
ofstream fout("gather.out");
int n, k, m;
vector<tuple<int, int, int>> g[755];
vector<point> detinuti;
unsigned long long distanta[755][755], dp[(1 << 16) + 5][20], graf[20][20][20];
queue<int> q;
bitset<755> viz;
void Read()
{
int w, x, y, z, nr = 0;
fin>>k>>n>>m;
detinuti.push_back({1, ++nr});
for(int i = 1;i <= k;++i)
fin>>w, detinuti.push_back({w, ++nr});
for(int i = 1;i <= m;++i)
{
fin>>w>>x>>y>>z;
g[w].push_back({x, y, z}); g[x].push_back({w, y, z});
}
}
void bellman(int start)
{
viz.reset();
for(int i = 0;i <= 750;++i)
for(int j = 0;j <= 750;++j)
distanta[i][j] = oo;
for(int i = 0;i <= k;++i)
distanta[start][i] = 0;
q.push(start);
viz.set(start);
int nod, vecin, cost, cap;
bool mod = false;
while(!q.empty())
{
nod = q.front();
q.pop();
for(auto it : g[nod])
{
vecin = get<0>(it), cost = get<1>(it), cap = get<2>(it);
mod = false;
for(int i = 0;i <= cap;++i)
for(int j = i;j <= cap;++j)
if(distanta[vecin][i] > distanta[nod][j] + cost)
{
mod = true;
distanta[vecin][i] = distanta[nod][j] + cost;
}
if(!viz.test(vecin) && mod)
q.push(vecin);
viz.set(vecin);
}
viz.reset(vecin);
}
}
void solve()
{
for(int i = 1;i < (1 << (k + 1));++i)
for(int j = 1;j <= k + 1;++j)
dp[i][j] = oo;
dp[1][1] = 0;
int nr = 0;
for(int i = 1;i <= (1 << (k + 1));++i)
if(i & 1)
{
nr = 0;
for(int h = 1;h <= k;++h)
if(i & (1 << h)) ++nr;
for(int j = 1;j <= k + 1;++j)
for(int h = 1;h <= k + 1;++h)
if(j != h)
{
if(!(i & (1 << (j - 1))) && graf[j][h][nr] != oo)
dp[i + (1 << (j - 1))][j] = min(dp[i + (1 << (j - 1))][j], dp[i][h] + (nr + 1) * graf[j][h][nr]);
if(graf[j][h][nr] != oo && dp[i][h] != oo)
dp[i][j] = min(dp[i][j], dp[i][h] + (nr + 1) * graf[j][h][nr]);
}
}
unsigned long long rez = oo;
for(int i = 1;i <= k + 1;++i)
rez = min(rez, dp[(1 << (k + 1)) - 1][i]);
fout<<rez;
}
void make_graph()
{
int nr = 0;
for(auto it : detinuti)
{
++nr;
bellman(it.first);
for(auto it1 : detinuti)
for(int i = 0;i <= k;++i)
if(it.first != it1.first && distanta[it1.first][i] < oo)
graf[it.second][it1.second][i] = distanta[it1.first][i];
}
/*for(int i = 1;i <= k + 1;++i, cout<<'\n')
for(int j = 1;j <= k + 1;++j)
for(int h = 0;h <= k;++h)
if(i != j)
cout<<i<<" "<<j<<" "<<graf[i][j][h]<<" "<<h<<'\n';*/
}
int main()
{
Read();
make_graph();
solve();
return 0;
}