Pagini recente » Cod sursa (job #1936200) | Cod sursa (job #1594471) | Cod sursa (job #1361364) | Cod sursa (job #2053571) | Cod sursa (job #1016940)
#include <fstream>
#include <vector>
#include <cstring>
#define maxn 760
#define vint vector<node>::iterator
#define inf 1LL*1000000000000
using namespace std;
ifstream fin("gather.in");
ofstream fout("gather.out");
struct node
{
int x,d,lim;
};
int n,k,m,x,y,w,z,hsize;
long long dp[1<<15][16],d[maxn],dist[16][16][16];
int h[maxn],hpoz[maxn],v[16],bits[1<<16];
vector <node> G[maxn];
int get_bits (int x)
{
int nr=0;
while (x!=0)
{
nr += (x&1);
x>>=1;
}
return nr;
}
void read ()
{
fin>>k>>n>>m;
for (int i=1; i<=k; ++i)
{
fin>>x;
v[i] = x;
}
for (int i=1; i<=m; ++i)
{
fin>>x>>y>>w>>z;
node in;
in.x = y;
in.d = w;
in.lim = z;
G[x].push_back (in);
in.x = x;
G[y].push_back (in);
}
}
inline int father (const int x)
{
return x>>1;
}
inline int left_son (const int x)
{
return x<<1;
}
inline int right_son (const int x)
{
return (x<<1)+1;
}
void upheap (int poz)
{
int pullout = h[poz];
while (d[pullout] < d[h[father(poz)]])
{
h[poz] = h[father(poz)];
hpoz[h[poz]] = poz;
poz >>=1;
}
h[poz] = pullout;
hpoz[h[poz]] = poz;
}
void downheap (int poz)
{
int pullout = h[poz],ok=0;
while (ok!=-1)
{
ok = -1;
if (left_son(poz) <= hsize && d[pullout] > d[h[left_son(poz)]])
ok =0;
if (right_son(poz) <= hsize && d[pullout] > d[h[right_son(poz)]])
{
if (ok==0)
{
if (d[h[right_son(poz)]] < d[h[left_son(poz)]])
ok = 1;
}
else ok = 1;
}
if (ok!=-1)
{
h[poz] = h[(poz<<1)+ok];
hpoz[h[poz]] = poz;
poz = (poz<<1)+ok;
}
}
h[poz] = pullout;
hpoz[h[poz]] = poz;
}
void dijkstra (int x, int l)
{
for (int i=1; i<=n+1; ++i)
{
h[i] = i;
hpoz[i] = i;
d[i] = inf;
}
hsize = n;
d[x] = 0;
swap (h[x],h[1]);
swap (hpoz[x],hpoz[1]);
while (d[h[1]] != inf)
{
int c = h[1];
h[1] = h[hsize];
hpoz[h[1]] = 1;
h[hsize] = n+1;
--hsize;
downheap (hpoz[h[1]]);
for (vint it = G[c].begin(); it!=G[c].end(); ++it)
{
if (it->lim < l)
{
continue;
}
if (d[it->x] > d[c] + it->d*(l+1))
{
d[it->x] = d[c] + it->d*(l+1);
upheap (hpoz[it->x]);
}
}
}
}
void paths ()
{
dijkstra (1,0);
for (int i=1; i<=k; ++i)
{
dp[1<<(i-1)][i] = d[v[i]];
}
for (int i=1; i<k; ++i)
{
for (int j=1; j<=k; ++j)
{
dijkstra (v[j],i);
for (int h=1; h<=k; ++h)
{
dist[i][j][h] = d[v[h]];
}
}
}
}
long long DP ()
{
for (int i=1; i<(1<<k); ++i)
{
for (int j=1; j<=k; ++j)
{
if (dp[i][j] == inf)
continue;
for (int h=1; h<=k; ++h)
{
if (i | (1<<(h-1)) != i)
{
dp[i|(1<<(h-1))][h] = min (dp[i|(1<<(h-1))][h], dp[i][j] + dist[bits[i]][j][h]);
}
}
}
}
long long ans = inf;
for (int i=1; i<=k; ++i)
{
ans = min (ans,dp[(1<<k)-1][i]);
}
return ans;
}
int main()
{
read ();
for (int i=0; i<(1<<k); ++i)
{
bits[i] = get_bits(i);
}
for (int i=0; i<(1<<k); ++i)
{
for (int j=1; j<=k; ++j)
dp[i][j] = inf;
}
paths ();
fout<<DP ();
return 0;
}