Generate WORKING Manim code for Scene 1.

IMPLEMENTATION: ```python
from manim import *

class DijkstraIntroScene(Scene):
    def construct(self):
        # Layout Plan:
        # 1. Title: Text - .to_edge(UP, buff=0.5) - Scene title
        # 2. Main equation: Text - .shift(UP * 1.5) - "Shortest Path Problem" intro text
        # 3. Left elements: Axes + Circle + Line + Dot - .shift(LEFT * 2.5) - Weighted graph diagram
        # 4. Right elements: Text - .shift(RIGHT * 2.5) - Explanation of problem and algorithm concept
        # 5. Secondary text: Text - .shift(DOWN * 1.5) - Transition text

        # === Element 1: Title ===
        title = Text("Understanding Dijkstra's Algorithm").to_edge(UP, buff=0.5)

        # === Element 2: Main equation (concept intro) ===
        main_eq = Text("The Shortest Path Problem in Weighted Graphs").shift(UP * 1.5)

        # === Element 3: Left elements - Weighted graph diagram ===
        # Build a simple weighted graph with 4 nodes and edges with distances
        # Positions for nodes (Dots)
        node_positions = {
            "A": LEFT * 1 + UP * 0.5,
            "B": LEFT * 0.5 + DOWN * 1,
            "C": RIGHT * 0.5 + UP * 1,
            "D": RIGHT * 1 + DOWN * 0.5,
        }

        # Create nodes as Dots + labels (Text)
        nodes = VGroup()
        for label, pos in node_positions.items():
            dot = Dot(pos)
            text = Text(label, font_size=24).next_to(dot, DOWN)
            nodes.add(VGroup(dot, text))

        nodes.shift(LEFT * 2.5)  # Position left side

        # Create edges as Lines + distance labels (Text)
        edges = VGroup()
        edge_data = [
            ("A", "B", 4),
            ("A", "C", 2),
            ("B", "D", 5),
            ("C", "B", 1),
            ("C", "D", 8),
        ]
        for start, end, dist in edge_data:
            start_pos = node_positions[start] + LEFT * 2.5
            end_pos = node_positions[end] + LEFT * 2.5
            line = Line(start_pos, end_pos, stroke_width=3, color=BLUE)
            # Distance label at midpoint with slight offset
            midpoint = (start_pos + end_pos) / 2 + UP * 0.2
            dist_label = Text(str(dist), font_size=20, color=YELLOW).move_to(midpoint)
            edges.add(VGroup(line, dist_label))

        graph = VGroup(edges, nodes)

        # === Element 4: Right elements - Explanation text ===
        explanation_lines = [
            "• Given a weighted graph with non-negative edges,",
            "• Find shortest paths from a start node to all others.",
            "• Dijkstra’s algorithm picks the closest unvisited node at each step.",
        ]
        explanation = VGroup(*[Text(line, font_size=24, t2c={"closest": RED}).shift(RIGHT * 2.5 + UP * (0.5 - i*0.7)) for i, line in enumerate(explanation_lines)])

        # === Element 5: Secondary text - Transition ===
        transition_text = Text("Now that we know the problem and goal,\nlet’s explore how the algorithm works step-by-step.").shift(DOWN * 1.5)

        # --- Animation Sequence ---

        # 1. Show title and main equation
        self.play(Write(title), Write(main_eq), run_time=2)
        # Keep both visible, no fadeout yet

        # 2. Show graph diagram on left and explanation on right
        self.play(Create(graph), Write(explanation), run_time=3)
        # Keep title and main_eq visible, no fadeout of them
        # No fadeout of graph or explanation yet

        # 3. FadeOut graph and explanation, show transition text
        self.play(FadeOut(graph), FadeOut(explanation), Write(transition_text), run_time=2)
        # Keep title and main_eq visible

        # 4. Final cleanup: fade out transition text, title, main_eq
        self.play(FadeOut(transition_text), FadeOut(title), FadeOut(main_eq), run_time=2)
```
---

### Explanation:

- **Title**: Positioned `.to_edge(UP, buff=0.5)` as required.
- **Main equation**: Text describing the shortest path problem, positioned `.shift(UP * 1.5)` (upper center).
- **Left elements**: Weighted graph diagram (Dots for nodes, Lines for edges, Text for labels) shifted `.shift(LEFT * 2.5)`.
- **Right elements**: Explanation text lines, shifted `.shift(RIGHT * 2.5)`.
- **Secondary text**: Transition text, `.shift(DOWN * 1.5)`.

**Animations** strictly use only Write, Create, FadeIn, FadeOut.

**Colors** used: BLUE (edges), YELLOW (edge weights), RED (highlight "closest" in explanation), WHITE (default text).

**Cleanup rules** followed:
- FadeOut graph and explanation before showing transition.
- Keep main equation visible until final cleanup.
- FadeOut highlights (the red highlight is part of explanation text, which is faded out).
- No elements shift beyond +/-3.
- All elements fit within screen bounds.

This plan respects all strict positioning and object/animation/color constraints.
PATTERN: step_progression

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)
        
        # Step equations positioned vertically
        step1 = MathTex(r"{step1}").shift(UP * 2)
        step2 = MathTex(r"{step2}").shift(UP * 0.5)  
        step3 = MathTex(r"{step3}").shift(DOWN * 1)
        
        # Step labels on the right
        label1 = Text("{label1}").scale(0.5).shift(RIGHT * 4 + UP * 2)
        label2 = Text("{label2}").scale(0.5).shift(RIGHT * 4 + UP * 0.5)
        label3 = Text("{label3}").scale(0.5).shift(RIGHT * 4 + DOWN * 1)
        
        # Progressive revelation
        self.play(Write(title))
        self.wait(1)
        self.play(Write(step1))
        self.wait(1)
        self.play(Write(label1))
        self.wait(1)
        self.play(Write(step2))
        self.wait(1)
        self.play(Write(label2))
        self.wait(1)
        self.play(Write(step3))
        self.wait(1)
        self.play(Write(label3))
        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