#include <stdio.h>
#include <stdlib.h>

#define MAX_ZONES 100

typedef struct {
    int priority;
    int supplies;
    int people_needing_rescue;
} Zone;

typedef struct {
    Zone zones[MAX_ZONES];
    int size;
} PriorityQueue;

// Function prototypes
void initializePriorityQueue(PriorityQueue *pq);
void insertZone(PriorityQueue *pq, Zone zone);
Zone extractMax(PriorityQueue *pq);

// Helper functions
void swap(Zone *a, Zone *b);
void heapify(PriorityQueue *pq, int i);

void initializePriorityQueue(PriorityQueue *pq) {
    pq->size = 0;
}

void insertZone(PriorityQueue *pq, Zone zone) {
    if (pq->size >= MAX_ZONES) return;
    pq->zones[pq->size] = zone;
    int i = pq->size;
    pq->size++;
    
    while (i != 0 && pq->zones[i].priority > pq->zones[(i - 1) / 2].priority) {
        swap(&pq->zones[i], &pq->zones[(i - 1) / 2]);
        i = (i - 1) / 2;
    }
}

Zone extractMax(PriorityQueue *pq) {
    if (pq->size <= 0) exit(-1);
    if (pq->size == 1) {
        pq->size--;
        return pq->zones[0];
    }

    Zone root = pq->zones[0];
    pq->zones[0] = pq->zones[pq->size - 1];
    pq->size--;
    heapify(pq, 0);
    
    return root;
}

void swap(Zone *a, Zone *b) {
    Zone temp = *a;
    *a = *b;
    *b = temp;
}

void heapify(PriorityQueue *pq, int i) {
    int largest = i;
    int left = 2 * i + 1;
    int right = 2 * i + 2;

    if (left < pq->size && pq->zones[left].priority > pq->zones[largest].priority)
        largest = left;
    if (right < pq->size && pq->zones[right].priority > pq->zones[largest].priority)
        largest = right;
    if (largest != i) {
        swap(&pq->zones[i], &pq->zones[largest]);
        heapify(pq, largest);
    }
}
#define MAX_VERTICES 100

int adjMatrix[MAX_VERTICES][MAX_VERTICES];

void initializeGraph() {
    for (int i = 0; i < MAX_VERTICES; i++) {
        for (int j = 0; j < MAX_VERTICES; j++) {
            adjMatrix[i][j] = 0;
        }
    }
}

void addEdge(int u, int v, int weight) {
    adjMatrix[u][v] = weight;
    adjMatrix[v][u] = weight; // Assuming it's an undirected graph
}
#define MAX_VERTICES 100

int adjMatrix[MAX_VERTICES][MAX_VERTICES];

void initializeGraph() {
    for (int i = 0; i < MAX_VERTICES; i++) {
        for (int j = 0; j < MAX_VERTICES; j++) {
            adjMatrix[i][j] = 0;
        }
    }
}

void addEdge(int u, int v, int weight) {
    adjMatrix[u][v] = weight;
    adjMatrix[v][u] = weight; // Assuming it's an undirected graph
}
typedef struct {
    int supplies[MAX_ZONES];
    int top;
} Stack;

void initializeStack(Stack *stack) {
    stack->top = -1;
}

void push(Stack *stack, int supply) {
    if (stack->top >= MAX_ZONES - 1) return;
    stack->supplies[++stack->top] = supply;
}

int pop(Stack *stack) {
    if (stack->top < 0) exit(-1);
    return stack->supplies[stack->top--];
}
typedef struct Person {
    int id;
    int rescue_time;
    struct Person *left, *right;
} Person;

Person* newPerson(int id, int time) {
    Person* temp = (Person*)malloc(sizeof(Person));
    temp->id = id;
    temp->rescue_time = time;
    temp->left = temp->right = NULL;
    return temp;
}

Person* insert(Person* node, int id, int time) {
    if (node == NULL) return newPerson(id, time);

    if (time < node->rescue_time)
        node->left = insert(node->left, id, time);
    else
        node->right = insert(node->right, id, time);

    return node;
}

void inorder(Person* root) {
    if (root != NULL) {
        inorder(root->left);
        printf("Person ID: %d, Rescue Time: %d\n", root->id, root->rescue_time);
        inorder(root->right);
    }
}
int main() {
    PriorityQueue pq;
    Stack supplyStack;
    Person *rescuedPeople = NULL;

    initializePriorityQueue(&pq);
    initializeStack(&supplyStack);
    initializeGraph();

    // Example insertion for Priority Queue
    Zone z1 = {1, 10, 5};
    Zone z2 = {2, 15, 3};
    insertZone(&pq, z1);
    insertZone(&pq, z2);

    // Insert rescued person into BST
    rescuedPeople = insert(rescuedPeople, 101, 5);  // ID 101, Rescue time 5

    // Print rescued people inorder
    inorder(rescuedPeople);

    // Example of moving a team
    Zone highestPriorityZone = extractMax(&pq);
    printf("Rescuing zone with priority: %d\n", highestPriorityZone.priority);

    // Handle supplies
    push(&supplyStack, 20);  // Add 20 supplies
    printf("Supplies used: %d\n", pop(&supplyStack));

    return 0;
}