Pagini recente » Cod sursa (job #1991494) | Cod sursa (job #2725050) | Cod sursa (job #3191360) | Cod sursa (job #618994) | Cod sursa (job #298642)
Cod sursa(job #298642)
#include <stdio.h>
#include <vector>
#include <string.h>
using namespace std;
#define MAX_N 512
#define MAX_P 64
#define INF 2147000000
int n, m, p, k, sol;
int stop[MAX_P];
vector <int> A[MAX_N], C[MAX_N];
int D[MAX_N][MAX_N];
int c[MAX_P][MAX_P][MAX_N];
struct heap {
int nod;
int cost;
} h[MAX_N * 2], aux;
int pheap[MAX_N], use[MAX_N];
void cit() {
freopen("team.in", "r", stdin);
freopen("team.out", "w", stdout);
scanf("%d", &p);
scanf("%d", &n);
scanf("%d", &m);
for (int i = 1; i <= m; i++) {
int p, q, c;
scanf("%d %d %d", &p, &q, &c);
A[p].push_back(q); C[p].push_back(c);
A[q].push_back(p); C[q].push_back(c);
}
for (int i = 1; i <= p; i++)
scanf("%d ", &stop[i]);
}
void heap_update(int poz) {
int gas = 0;
//incerc sa ma duc in jos
while (poz > 1 && h[poz / 2].cost > h[poz].cost) {
aux = h[poz / 2]; h[poz / 2] = h[poz]; h[poz] = aux;
pheap[h[poz / 2].nod] = poz / 2;
pheap[h[poz].nod] = poz;
gas = 1; poz /= 2;
}
if (!gas) {
//incerc sa ma duc in sus in heap
while ((h[poz * 2].cost < h[poz].cost && poz * 2 <= k) ||
(h[poz * 2 + 1].cost < h[poz].cost && poz * 2 + 1<= k)) {
int next = poz * 2;
if (poz * 2 + 1 <= k && h[poz * 2 + 1].cost < h[poz * 2].cost)
next = poz * 2 + 1;
aux = h[poz]; h[poz] = h[next]; h[next] = aux;
pheap[h[poz].nod] = poz; pheap[h[next].nod] = next;
poz = next;
}
}
}
void dijkstra() {
//aflu distanta de la toate punctele de oprire la orice punct din graf cu algoritmul
//lui dijkstra
for (int i = 1; i <= p; i++)
for (int j = 1; j <= n; j++)
D[i][j] = INF;
for (int i = 1; i <= p; i++) {
//lucrez pentru punctul stop[i]
D[i][stop[i]] = 0;
memset(use, 0, sizeof(use));
memset(pheap, 0, sizeof(pheap));
memset(use, 0, sizeof(use));
k = 1;
h[1].nod = stop[i]; h[1].cost = 0;
pheap[stop[i]] = 1;
while (k) {
int len = A[h[1].nod].size();
for (int j = 0; j < len; j++) {
int NewNod = A[h[1].nod][j];
int CNew = h[1].cost + C[h[1].nod][j];
if (use[NewNod] == 0) {
if (pheap[NewNod] == 0) {
h[++k].nod = NewNod;
h[k].cost = CNew;
pheap[NewNod] = k;
heap_update(k);
}
else {
int poz = pheap[NewNod];
if (h[poz].cost > CNew) {
h[poz].cost= CNew;
heap_update(poz);
}
}
}
}
use[h[1].nod] = 1;
D[stop[i]][h[1].nod] = D[h[1].nod][stop[i]] = h[1].cost;
//scot primul element din heap
pheap[h[1].nod] = 0;
h[1] = h[k];
pheap[h[k].nod] = 1;
h[k].nod = h[k].cost = 0;
k--;
heap_update(1);
}
}
}
void dinamica() {
//am aflat distanta intre oricare stop[i] si orice alt nod, in D[i][nod]
//c[d][i][k] = costul minim pentru a duce persoanele de pe pozitiile
// i...i + d acasa, ele fiind in acest moment in nodul stop[k]
for (int d = 0; d < p; d++)
for (int i = 1; i + d <= p; i++)
for (int k = 1; k <= p; k++)
c[d][i][stop[k]] = INF;
sol = INF;
for (int d = 0; d < p; d++)
for (int i = 1; i + d <= p; i++)
for (int k = 1; k <= p; k++) {
for (int t = 0; t <= d; t++) {
//persoana de pe pozitia i + t se va desparti de grup
int val = D[stop[k]][stop[i + t]];
if (t - 1 >= 0) val += c[t - 1][i][stop[i + t]];
if (d - t - 1 >= 0) val += c[d - t - 1][i + t + 1][stop[i + t]];
if (c[d][i][stop[k]] > val)
c[d][i][stop[k]] = val;
}
if (d == p - 1)
if (c[d][i][stop[k]] + D[1][stop[k]] < sol)
sol = c[d][i][stop[k]] + D[1][stop[k]];
}
printf("%d\n", sol);
}
int main() {
cit();
dijkstra();
dinamica();
return 0;
}