Generate WORKING Manim code for Scene 1.

IMPLEMENTATION: ```python
from manim import *

class DijkstraIntro(Scene):
    def construct(self):
        # Layout Plan:
        # 1. Title: Text - .to_edge(UP, buff=0.5) - Scene title
        # 2. Main equation: Text (or MathTex) - .shift(UP * 1.5) - Key concept statement
        # 3. Secondary text: Text - .shift(DOWN * 1.5) - Additional explanation
        # 4. Left elements: Diagram of weighted graph - .shift(LEFT * 2.5) - Visual focus
        # 5. Right elements: Highlighted start node and paths - .shift(RIGHT * 2.5) - Emphasize start and paths

        # --- Element 1 ---
        title = Text("Understanding Shortest Paths & Dijkstra's Algorithm", color=WHITE).to_edge(UP, buff=0.5)

        # --- Element 2 ---
        main_eq = Text(
            "Dijkstra's algorithm finds shortest paths\n"
            "from a start node to all others in a weighted graph",
            color=YELLOW
        ).shift(UP * 1.5)

        # --- Element 3 ---
        secondary_text = Text(
            "Shortest path problem: find minimum total weight path\n"
            "in a graph with non-negative edge weights",
            color=WHITE
        ).shift(DOWN * 1.5)

        # --- Left element: Weighted graph diagram ---
        # Create nodes as dots with labels
        nodes = {
            "A": Dot(point=LEFT * 1 + UP * 0.5, color=BLUE),
            "B": Dot(point=LEFT * 0.5 + DOWN * 1, color=BLUE),
            "C": Dot(point=RIGHT * 0.5 + UP * 1, color=BLUE),
            "D": Dot(point=RIGHT * 1 + DOWN * 0.5, color=BLUE),
        }
        node_labels = {
            k: Text(k, color=WHITE).next_to(v, DOWN if k in ["A", "C"] else UP, buff=0.1)
            for k, v in nodes.items()
        }

        # Edges as Lines with weights as Text
        edges = [
            (nodes["A"], nodes["B"], 4),
            (nodes["A"], nodes["C"], 2),
            (nodes["B"], nodes["D"], 5),
            (nodes["C"], nodes["B"], 1),
            (nodes["C"], nodes["D"], 8),
        ]
        edge_lines = []
        edge_weights = []
        for start, end, w in edges:
            line = Line(start.get_center(), end.get_center(), color=WHITE)
            edge_lines.append(line)
            # Place weight label at midpoint shifted slightly perpendicular
            midpoint = (start.get_center() + end.get_center()) / 2
            direction = (end.get_center() - start.get_center())
            perp = np.array([-direction[1], direction[0], 0])
            perp = perp / np.linalg.norm(perp) * 0.2
            weight_text = Text(str(w), color=YELLOW).scale(0.6).move_to(midpoint + perp)
            edge_weights.append(weight_text)

        graph_group = VGroup(*edge_lines, *edge_weights, *nodes.values(), *node_labels.values())
        graph_group.shift(LEFT * 2.5)

        # --- Right element: Highlight start node and possible paths ---
        # Highlight start node A with SurroundingRectangle
        start_node_rect = SurroundingRectangle(nodes["A"], color=GREEN, buff=0.15)
        # Highlight possible paths from A with arrows (A->C, A->B)
        arrow_ac = Arrow(start=nodes["A"].get_center(), end=nodes["C"].get_center(), color=RED, buff=0)
        arrow_ab = Arrow(start=nodes["A"].get_center(), end=nodes["B"].get_center(), color=RED, buff=0)

        # Group highlights and shift right
        highlights = VGroup(start_node_rect, arrow_ac, arrow_ab).shift(RIGHT * 2.5)

        # --- Animation Sequence ---

        # 1. Write title (0.8s), no cleanup
        self.play(Write(title), run_time=0.8)

        # 2. Write main equation (1.5s), no cleanup
        self.play(Write(main_eq), run_time=1.5)

        # 3. Write secondary text (1.5s), no cleanup
        self.play(Write(secondary_text), run_time=1.5)

        # 4. Create graph diagram on left (2s)
        self.play(Create(graph_group), run_time=2)

        # 5. FadeOut secondary text (1s)
        self.play(FadeOut(secondary_text), run_time=1)

        # 6. Create highlights on right (start node + arrows) (2s)
        self.play(Create(highlights), run_time=2)

        # 7. FadeOut highlights (1s)
        self.play(FadeOut(highlights), run_time=1)

        # 8. FadeOut graph diagram (1.5s)
        self.play(FadeOut(graph_group), run_time=1.5)

        # 9. Write transition text (secondary text position) (2s)
        transition_text = Text(
            "Now that we understand the problem,\n"
            "let's explore how Dijkstra’s algorithm\n"
            "finds shortest paths step-by-step.",
            color=WHITE
        ).shift(DOWN * 1.5)
        self.play(Write(transition_text), run_time=2)

        # 10. Final cleanup: FadeOut transition text (1s)
        self.play(FadeOut(transition_text), run_time=1)

        # Keep title and main_eq visible at end
        self.wait(1)
```
---

### Explanation:

- **Title** is positioned `.to_edge(UP, buff=0.5)` as required.
- **Main equation** is positioned `.shift(UP * 1.5)` centered.
- **Secondary text** and **transition text** are positioned `.shift(DOWN * 1.5)` centered.
- **Graph diagram** is shifted left by 2.5 units.
- **Highlights** (start node rectangle and arrows) are shifted right by 2.5 units.
- All elements fit within the screen bounds (-6 to +6 horizontally, -3.5 to +3.5 vertically).
- Only allowed Manim objects and animations are used.
- Colors limited to BLUE, RED, GREEN, YELLOW, WHITE.
- Cleanup rules are followed: fade out old descriptions before new ones, fade out highlights after showing, keep main equation visible until the end.
- The animation sequence is clear and simple, following the instructions strictly.
PATTERN: function_graph

CRITICAL CONSTRAINTS:
1. Use ONLY these objects: Text, MathTex, Axes, Circle, Rectangle, Line, Arrow, Dot, SurroundingRectangle, VGroup
2. Use ONLY these animations: Write, Create, FadeIn, FadeOut 
3. Use ONLY these colors (no quotes): BLUE, RED, GREEN, YELLOW, WHITE, ORANGE, PURPLE
4. NO undefined objects like VideoFile, Slider, ImageMobject
5. NO Unicode characters - use LaTeX: \sqrt{} not √, \pm not ±

POSITIONING REQUIREMENTS (CRITICAL):
- Each element MUST have unique position within screen bounds
- SAFE positions only: .to_edge(UP), .shift(UP*1.5), .shift(DOWN*1.5), .shift(LEFT*2.5), .shift(RIGHT*2.5)
- NO extreme shifts: avoid UP*3, DOWN*3, LEFT*4, RIGHT*4 (goes off-screen)
- NO overlapping: if one element uses .shift(UP*1.5), others must use different positions
- Test positions: Title=top, Main=upper center, Secondary=lower center, Sides=left/right

TEMPLATE TO ADAPT:

        # Title at top
        title = Text("{title}").scale(0.8).to_edge(UP, buff=0.5)
        
        # Axes positioned in lower area
        axes = Axes(
            x_range=[-3, 3, 1],
            y_range=[-2, 4, 1], 
            x_length=6,
            y_length=4,
            axis_config={{"color": BLUE}}
        ).shift(DOWN * 0.5)
        
        # Function plot
        function = axes.plot(lambda x: {function_expr}, color=RED)
        
        # Equation display
        equation = MathTex(r"{equation}").shift(UP * 1.5)
        
        # Animation sequence
        self.play(Write(title))
        self.wait(1)
        self.play(Write(equation))
        self.wait(1)
        self.play(Create(axes))
        self.wait(1)
        self.play(Create(function))
        self.wait(2)
                

Replace placeholders with scene-specific values and ensure working Manim code.

Generate complete Python code:
SMART POSITIONING REQUIREMENTS:
- Analyze the content TYPE first: equation, diagram, comparison, process
- Position based on content meaning, not just arbitrary rules
- Main subject (equation/diagram) should be CENTER or slightly UP
- Supporting text should be BELOW the main subject
- Comparisons should use LEFT/RIGHT positioning
- Sequential content should use TOP-to-BOTTOM flow
- NEVER fade out main content - only temporary highlights

CAREFULLY IMPLEMENT THIS