Вы находитесь на странице: 1из 6

#include<stdio.

h>

int distance[1000];
int visit[1000];
int previous[1000];
int bykKota;

int bykEdge[1000];

struct graph {
int to;
int cost;
};

graph adjList[1000][11];

struct tdata {
int cost;
int node;
};

tdata heap[2000];
int count;

// compare akan return -1 Jika a < b


// return 0 jika a == b
// return 1 jika a > b
// tdata a < tdata b, JIKA
// a.cost < b.cost
int compare(tdata a, tdata b) {
if (a.cost < b.cost) return -1;
else if (a.cost == b.cost) {
if (a.node < b.node) return -1;
else if (a.node == b.node) return 0;
else return 1;
} else {
return 1;
}
}

void heapDown(int idx) {


tdata curValue = heap[idx];
int curIdx = idx;

// Cek dulu apakah node kiri lebih kecil dari node sekarang
// 2*idx <= count untuk mengecek apakah kita punya anak kiri.
if (2*idx <= count && compare(heap[2*idx], curValue) < 0) {
curIdx = 2*idx;
curValue = heap[2*idx];
}

// lalu cek apakah node kanan lebih kecil dari node kiri dan node skrg
// 2*idx+1 <= count untuk mengecek apakah kita punya anak kanan.
if ( (2*idx+1) <= count && compare(heap[2*idx+1], curValue) < 0) {
curIdx = 2*idx+1;
curValue = heap[2*idx+1];
}
// gak perlu heapdown ke bawah lagi..
// kalau yang sekarang sudah yang paling kecil
if (curIdx == idx) {
return;
}

// swap dulu nilai node mereka


tdata temp = heap[idx];
heap[idx] = heap[curIdx];
heap[curIdx] = temp;

// heapdown lagi ke index tersebut


heapDown(curIdx);
}

tdata extractMinimum() {

// sebenarnya heap tidak boleh di extractMinimum jika dia kosong


// tapi jika di lakukan, maka kita kasih safety guard dengan mengembalikan
// sebuah nilai yang "tidak mungkin" -- dalam kasus ini infinity (2^30)
if (count <= 0) {
tdata retValue;
retValue.cost = (1 << 30);
retValue.node = -1;
return retValue; // return infinity
}
if (count == 1) {
count--;
return heap[1];
}

tdata rootValue = heap[1];


heap[1] = heap[count];
count--;
heapDown(1);

return rootValue;
}

void insert(int cost, int node) {


if (count >= 1999) {
printf("Kepenuhan\n");
return;
}

// masukkan angka tersebut di node paling "belakang"


count++;
heap[count].cost = cost;
heap[count].node = node;

// setelah di masukkan, harus compare ke parent2-nya


int curIdx = count;
// selama masih belum ada di root (idx 1), maka cek..
// apakah parent idx tersebut lebih besar?
// Jika iya, maka swap, dan naik ke atas..
while(curIdx != 1 && compare(heap[curIdx], heap[curIdx/2]) < 0) {
// swap!
tdata temp = heap[curIdx];
heap[curIdx] = heap[curIdx/2];
heap[curIdx/2] = temp;

// naik ke atas
curIdx = curIdx / 2;
}

// dijkstra O(n^2)
int dijkstra(int from, int to) {

for(int i=0; i<bykKota; i++) {


visit[i] = 0;
distance[i] = (1<<30); // infinity
previous[i] = -1;
}

distance[from] = 0;
insert(distance[from], from);

// selama masih ada data di priority queue


while(count > 0) {

tdata curNode = extractMinimum();


int idx = curNode.node;
if (visit[idx]) continue;
visit[idx] = 1;
for(int k=0; k<bykEdge[idx]; k++) {

int edgeCost = adjList[idx][k].cost;


int nextKota = adjList[idx][k].to;

if (distance[idx] + edgeCost < distance[ nextKota ]) {


distance[nextKota] = distance[idx] + edgeCost;
previous[nextKota] = idx;
insert(distance[nextKota], nextKota); // di update, maka
masukkan ke pq
}
}

}
return distance[to];

void tracePath(int idx) {


if (idx == -1) return;
tracePath(previous[idx]);
printf(" %d ", idx);
}

int main() {
count = 0;
for(int i=0; i<1000; i++) {
bykEdge[i] = 0;
}
/*bykEdge[0] = 2;
bykEdge[1] = 2;
bykEdge[2] = 3;
bykEdge[3] = 3;
bykEdge[4] = 1;
bykEdge[5] = 1;

// adjMatrix[0][1] = 30;
adjList[0][0].cost = 30;
adjList[0][0].to = 1;
adjList[1][0].cost = 30;
adjList[1][0].to = 0;

// adjMatrix[0][2] = 10;
adjList[0][1].cost = 10;
adjList[0][1].to = 2;
adjList[2][0].cost = 10;
adjList[2][0].to = 0;

// adjMatrix[1][3] = 10;
adjList[1][1].cost = 10;
adjList[1][1].to = 3;
adjList[3][0].cost = 10;
adjList[3][0].to = 1;

// adjMatrix[2][3] = 50;
adjList[2][1].cost = 50;
adjList[2][1].to = 3;
adjList[3][1].cost = 50;
adjList[3][1].to = 2;

// adjMatrix[2][4] = 15;
adjList[2][2].cost = 15;
adjList[2][2].to = 4;
adjList[4][0].cost = 15;
adjList[4][0].to = 2;

// adjMatrix[3][5] = 17;
adjList[3][2].cost = 17;
adjList[3][2].to = 5;
adjList[5][0].cost = 17;
adjList[5][0].to = 3;

bykKota = 6;
*/

bykEdge[0] = 3;
bykEdge[1] = 4;
bykEdge[2] = 5;
bykEdge[3] = 3;
bykEdge[4] = 3;
bykEdge[5] = 3;

// adjMatrix[A][B] = 2;
adjList[0][0].cost = 2;
adjList[0][0].to = 1;
adjList[1][0].cost = 2;
adjList[1][0].to = 0;

// adjMatrix[A][C] = 1;
adjList[0][1].cost = 1;
adjList[0][1].to = 2;
adjList[2][0].cost = 1;
adjList[2][0].to = 0;

// adjMatrix[A][F] = 4;
adjList[0][2].cost = 4;
adjList[0][2].to = 5;
adjList[5][0].cost = 4;
adjList[5][0].to = 0;

// adjMatrix[B][C] = 5;
adjList[1][1].cost = 5;
adjList[1][1].to = 2;
adjList[2][1].cost = 5;
adjList[2][1].to = 1;

// adjMatrix[B][D] = 3;
adjList[1][2].cost = 3;
adjList[1][2].to = 3;
adjList[3][0].cost = 3;
adjList[3][0].to = 1;

// adjMatrix[B][E] = 4;
adjList[1][3].cost = 4;
adjList[1][3].to = 4;
adjList[4][0].cost = 4;
adjList[4][0].to = 1;

// adjMatrix [C][D] = 1
adjList[2][1].cost = 1;
adjList[2][1].to = 3;
adjList[3][1].cost = 1;
adjList[3][1].to = 1;
// adjMatrix [C][E] = 2
adjList[2][2].cost = 2;
adjList[2][2].to = 4;
adjList[4][1].cost = 2;
adjList[4][1].to = 2;
// adjMatrix [C][F] = 3
adjList[2][3].cost = 3;
adjList[2][3].to = 6;
adjList[5][1].cost = 3;
adjList[5][1].to = 2;
// adjMatrix [D][E] = 2
adjList[3][2].cost = 2;
adjList[3][2].to = 4;
adjList[4][2].cost = 2;
adjList[4][2].to = 3;
// adjMatrix [E][F] = 1
adjList[4][3].cost = 1;
adjList[4][3].to = 5;
adjList[5][2].cost = 1;
adjList[5][2].to = 3;
bykKota = 6;
int kota;
while(1){
printf("Masukkan Kota:");
scanf("%d",&kota);
printf("%d\n", dijkstra(0, kota));
tracePath(kota);
puts("");

for(int i=0; i<bykKota; i++) {


printf(" %d ", distance[i]);
}
puts("");
}

/*printf("%d\n", dijkstra(0, 4));


tracePath(4);
puts("");

for(int i=0; i<bykKota; i++) {


printf(" %d ", distance[i]);
}*/
return 0;
}

Вам также может понравиться