Pagini recente » Cod sursa (job #12441) | Cod sursa (job #2962883) | Cod sursa (job #1582580) | Cod sursa (job #2722755) | Cod sursa (job #2649820)
#include <bits/stdc++.h>
#define point pair<int, int>
#define dist first
#define nod second
#define oo 0x3f3f3f3f
using namespace std;
ifstream fin("gather.in");
ofstream fout("gather.out");
int n, k, m;
vector<tuple<int, int, int>> g[750];
vector<point> detinuti;
int distanta[17][17], dp[(1 << 15) + 5][17], graf[17][17][17];
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();
memset(distanta, oo, sizeof(distanta));
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()
{
memset(dp, oo, sizeof(dp));
dp[0][1] = 0;
for(int i = 2;i <= k + 1;++i)
dp[1 + (1 << (i - 1))][i] = graf[1][i][0];
int nr;
for(int i = 2;i < (1 << (k + 1));++i)
if(1 & i)
{
nr = 0;
for(int h = 1;h <= k;++h)
if(i & (1 << h)) ++nr;
if(nr <= 1)
continue;
for(int j = 1;j <= k + 1;++j)
for(int h = 1;h <= k + 1;++h)
if(j != h)
{
if(j > 1 && i & (1 << (j - 1)))
dp[i][j] = min(dp[i][j], dp[i - (1 << (j - 1))][h] + nr * graf[j][h][nr - 1]);
dp[i][j] = min(dp[i][j], dp[i][h] + (nr + 1) * graf[j][h][nr]);
}
}
int 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;
}