Pagini recente » Cod sursa (job #1812785) | Cod sursa (job #2518232) | Cod sursa (job #293924) | Cod sursa (job #1249689) | Cod sursa (job #1709462)
#include <cstdio>
#include <queue>
#include <iostream>
#define NMAX 150001
#define INF 1<<30
using namespace std;
int T,N;
struct punct
{
int x, y;
}P[NMAX];
int H[NMAX],heap_size; // retin heap-ul
int poz[NMAX]; // retin pozitia din heap a punctului i
int cmin[NMAX],total; //costul minim pentru i;
bool uz[NMAX];
//priority_queue <pair<int, int> > pq;
int dist(int i, int j);
void reset();
void apm();
void make_heap();
void scufunda(int i);
void promote(int i);
int scoate();
int modul(int x)
{
if (x < 0) return -x;
return x;
}
int main()
{
freopen("metrou4.in", "r", stdin);
freopen("metrou4.out", "w", stdout);
cin >> T;
int test; int i;
for (test = 0; test < T; test++)
{
cin >> N;
reset();
for (i = 1; i <= N; i++)
cin >> P[i].x >> P[i].y;
apm();
cout << total << '\n';
}
return 0;
}
void apm()
{
int i;
uz[1] = 1;
H[1] = 1;
poz[1] = 1;
for (i = 2; i <= N; i++)
{
H[i-1] = i;
cmin[i] = dist(1, i);
poz[i] = i;
}
heap_size = N - 1;
make_heap();
int nr = 2;
for (nr = 2; nr <= N; nr++)
{
int vecin = scoate();
uz[vecin] = 1;
total += cmin[vecin];
for (i = 1; i <= N; i++)
{
if (!uz[i] && cmin[i] > dist(vecin, i))
{
cmin[i] = dist(vecin, i);
promote(poz[i]); //promoveaza din pozitia din heap de pe care se afla nodul i
}
}
}
}
int dist(int i, int j)
{
int d = 0;
d = modul(P[i].x - P[j].x) + modul(P[i].y - P[j].y);
return d;
}
void reset()
{
int i;
for (i = 1; i <= N; i++)
{
cmin[i] = INF;
uz[i] = 0;
}
total = 0;
}
void make_heap()
{
int i;
for (i = heap_size / 2; i >= 1; i--)
scufunda(i);
}
void scufunda(int i)
{
//scufund nodul i;
while (1)
{
int fiu = 2 * i;
if (fiu < heap_size && cmin[H[fiu + 1]] < cmin[H[fiu]])
fiu++;
if (fiu > heap_size) return;
//in fiu am fiul minim acum, pe el trebuie sa il pun;
if (cmin[H[i]] > cmin[H[fiu]])
{
swap(poz[H[i]], poz[H[fiu]]); //interschimb pozitiile pe care se gasesc in heap
swap(H[i], H[fiu]);// interschimb nodurile din heap
i = fiu;
}
else return;
}
}
int scoate()
{
//returneaza nodul cel mai apropiat de apm
int nod = H[1];
poz[H[heap_size]] = 1;
poz[nod] = -1;
swap(H[1], H[heap_size]);
heap_size--;
scufunda(1);
return nod;
}
void promote(int i)
{
//urca nodul de pe pozitia i din heap;
while (1)
{
int tata = i / 2;
if (tata < 1)
return;
if (cmin[H[tata]] > cmin[H[i]])
{
//trebuie sa le interchimb;
swap(poz[H[tata]], poz[H[i]]); //interschimb pozitiile pe care se gasesc in heap
swap(H[i], H[tata]);// interschimb nodurile din heap
i = tata;
}
else
return;
}
}