use pie_core::FibHeap;
fn main() {
println!("--- Fibonacci Heap Showcase ---\n");
let mut heap = FibHeap::<i32, &'static str>::new();
println!("1. Initial empty heap:");
println!("{heap}");
println!("\n2. Pushing elements 5, 10, and 3.");
println!(" Each new element becomes a new root in the heap.");
heap.push(5, "apple");
heap.push(10, "orange");
heap.push(3, "banana");
println!("{heap}");
println!("\n3. Pushing more elements (20, 15) and then popping the min (3).");
println!(" Popping triggers CONSOLIDATION, which links roots of the same degree.");
let handle_to_decrease = heap.push(20, "grape");
heap.push(15, "melon");
heap.pop(); println!("{heap}");
println!(" The heap is now a single tree rooted at 'apple'(5).");
println!("\n4. Decreasing key of 'grape' from 20 to 2.");
println!(" This violates the heap property, causing a CUT.");
let _ = heap.decrease_key(handle_to_decrease, 2);
println!("{heap}");
println!(" - 'grape'(2) is now a root and the new minimum.");
println!(" - Its former parent, 'melon'(15), is now marked (M) because it lost a child.");
println!("\n\n--- 5. A True Cascading Cut Demonstration ---");
println!(" To see a multi-level cascade, we need a tall tree with specific properties.");
let mut cascade_heap = FibHeap::<i32, &'static str>::new();
println!("\n Step A: Build the required tree structure.");
let _h20 = cascade_heap.push(20, "Great-Grandparent");
let _h30 = cascade_heap.push(30, "GGP-Sibling-1");
let _h40 = cascade_heap.push(40, "GGP-Sibling-2");
let _h50 = cascade_heap.push(50, "P-Sibling");
let _h60 = cascade_heap.push(60, "Grandparent");
let h70 = cascade_heap.push(70, "GP-Sibling");
let h80 = cascade_heap.push(80, "Parent");
let h90 = cascade_heap.push(90, "Child");
cascade_heap.push(1, "temp");
cascade_heap.pop();
println!("{cascade_heap}");
println!(" The structure now contains the 4-level chain we need for our test:");
println!(" GGP(20) -> GP(60) -> P(80) -> C(90)");
println!("\n Step B: Mark the 'Grandparent' and 'Parent' nodes.");
let _ = cascade_heap.decrease_key(h70, 18);
let _ = cascade_heap.decrease_key(h90, 17);
println!("{cascade_heap}");
println!(" - 'GP-Sibling'(18) and 'Child'(17) are now roots.");
println!(" - 'Parent'(80) is marked (M) because it lost its child.");
println!(" - 'Grandparent'(60) is also marked (M) for the same reason.");
println!("\n Step C: Cut 'Parent'(80) from the marked 'Grandparent'(60).");
println!(" This triggers the multi-level cascading cut.");
let _ = cascade_heap.decrease_key(h80, 16);
println!("{cascade_heap}");
println!(" - 'Parent'(16) is cut from 'Grandparent' and becomes a root. Its mark is cleared.");
println!(" - The cut CASCADES: 'Grandparent'(60) was marked and just lost a child, so it is");
println!(" ALSO cut from 'Great-Grandparent'(20). It becomes a new root and its mark is cleared.");
println!(" - The cascade stops at 'Great-Grandparent'(20). It lost a child ('Grandparent')");
println!(" but is already a root and is therefore not marked (M).");
println!("\n--- Showcase complete ---");
}