Pagini recente » ONIS 2014, Runda 1 | Profil andreifirst | Profil Al3ks1002 | Cod sursa (job #2299066) | Cod sursa (job #115576)
Cod sursa(job #115576)
#include <cstdio>
#include <vector>
#include <memory.h>
using namespace std;
const char iname[] = "gather.in";
const char oname[] = "gather.out";
#define MAXK 16
#define MAXN 755
#define MAXM 1255
#define INF 1e9
#define MIN(a, b) ((a) < (b) ? (a) : (b))
int K, N, M, P[MAXK];
int C[1 << MAXK][MAXK];
int S[MAXK], T[MAXK];
struct muchie {
int x, y, cst, cap;
} E[MAXM];
int D[MAXN];
int h(int s, int srs, int dst)
{
int cnt = 0;
for (int i = 0; i < K; ++ i) if ((s >> i) & 1)
cnt ++;
if (cnt == 0) if (srs != 1)
return INF;
// cnt <= cap
for (int i = 1; i <= N; ++ i)
D[i] = INF;
D[srs] = 0;
for (int i = 1; i <= N; ++ i)
for (int j = 0; j < M; ++ j) if (E[j].cap >= cnt) {
if (D[E[j].x] > D[E[j].y] + E[j].cst * (cnt ? cnt : 1))
D[E[j].x] = D[E[j].y] + E[j].cst * (cnt ? cnt : 1);
if (D[E[j].y] > D[E[j].x] + E[j].cst * (cnt ? cnt : 1))
D[E[j].y] = D[E[j].x] + E[j].cst * (cnt ? cnt : 1);
}
return D[dst];
}
void g(int i, int s, int t, int p)
{
if (i == K) {
for (int j = 0; j < K; ++ j) if ((s >> j) & 1)
{
// deplaseaza |s| detinuti de la P[j] la P[p]
if (s && (t ^ s)) {
C[t][p] = MIN(C[t][p], C[s][j] + C[t ^ s][p] + h(s, P[j], P[p]));
// printf("%d\n", s);
}
}
} else if (i < K) {
g(i+1, s, t, p);
if ((t >> i) & 1)
g(i+1, s | (1 << i), t, p);
}
}
int main(void)
{
freopen(iname, "r", stdin);
freopen(oname, "w", stdout);
scanf("%d %d %d", &K, &N, &M);
for (int i = 0; i < K; ++ i)
scanf("%d", &P[i]);
for (int i = 0; i < M; ++ i)
scanf("%d %d %d %d", &E[i].x, &E[i].y, &E[i].cst, &E[i].cap);
for (int i = 0; i < 1 << MAXK; ++ i)
for (int j = 0; j < MAXK; ++ j) C[i][j] = INF;
for (int s = 1; s < 1 << K; ++ s) {
if ((s & (s - 1)) == 0) {
// deplasez pe G in locatie
for (int j = 0; j < K; ++ j) if ((s >> j) & 1)
C[s][j] = h(0, 1, P[j]);
} else {
for (int j = 0; j < K; ++ j) if ((s >> j) & 1)
g(0, 0, s, j);
// printf(":)\n");
}
}
int sup = (1 << K) - 1;
int min = INF;
for (int i = 0; i < K; ++ i)
if (min > C[sup][i]) min = C[sup][i];
printf("%d\n", min);
return 0;
}