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. Visual_Focus: Diagram (Circles, Lines, Arrows, Text) - .shift(LEFT * 2.5) - Weighted graph diagram
        # 3. Content Text: Text - .shift(RIGHT * 2.5) - Explanation text (intro to shortest path problem and Dijkstra's purpose)
        # 4. Main Equation: MathTex - .shift(UP * 1.5) - Core statement of what Dijkstra solves
        # 5. Secondary Text: Text - .shift(DOWN * 1.5) - Transition sentence

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

        # 2. Visual_Focus: Weighted graph diagram on left side
        # Create nodes as Circles with labels (A, B, C, D)
        nodes = {}
        node_positions = {
            "A": LEFT * 2 + UP * 1,
            "B": LEFT * 1 + UP * 0,
            "C": LEFT * 3 + DOWN * 0,
            "D": LEFT * 1 + DOWN * 1,
        }
        for name, pos in node_positions.items():
            nodes[name] = Circle(radius=0.3, color=BLUE).move_to(pos)
        # Node labels
        labels = {
            name: Text(name, color=WHITE).move_to(nodes[name].get_center())
            for name in nodes
        }
        # Edges with weights (Lines + weight Text)
        edges = []
        weights = []
        # Edges: A-B(4), A-C(2), B-C(5), B-D(10), C-D(3)
        edge_data = [
            ("A", "B", 4),
            ("A", "C", 2),
            ("B", "C", 5),
            ("B", "D", 10),
            ("C", "D", 3),
        ]
        for start, end, w in edge_data:
            line = Line(nodes[start].get_center(), nodes[end].get_center(), color=WHITE)
            edges.append(line)
            # Weight label at midpoint shifted slightly perpendicular
            midpoint = (nodes[start].get_center() + nodes[end].get_center()) / 2
            # Vector perpendicular to edge for offset
            direction = nodes[end].get_center() - nodes[start].get_center()
            perp = np.array([-direction[1], direction[0], 0])
            perp = perp / np.linalg.norm(perp) * 0.3
            weight_label = Text(str(w), color=YELLOW).scale(0.6).move_to(midpoint + perp)
            weights.append(weight_label)

        # 3. Content Text on right side: introduction to shortest path problem and Dijkstra's purpose
        content_text = Text(
            "Shortest path problems in graphs\n"
            "Dijkstra's algorithm finds the shortest path\n"
            "from a starting node to all others\n"
            "in a weighted graph with non-negative edges.\n"
            "Weights represent distances or costs."
        ).scale(0.5).set_color(WHITE).shift(RIGHT * 2.5)

        # 4. Main Equation (Core statement) - Upper center
        main_eq = MathTex(
            r"\text{Find shortest paths from } s \text{ to all nodes}",
            color=GREEN
        ).shift(UP * 1.5)

        # 5. Secondary Text (Transition) - Lower center
        transition_text = Text(
            "Now that we know what problem Dijkstra’s algorithm solves,\n"
            "let’s explore how it works step-by-step.",
            color=WHITE
        ).scale(0.6).shift(DOWN * 1.5)

        ### Animation Sequence ###

        # Step 1: Show title and main equation
        self.play(Write(title), Write(main_eq), run_time=2)
        # Keep main_eq visible, fade out title after a pause
        self.wait(1)
        self.play(FadeOut(title))

        # Step 2: Show weighted graph diagram on left and content text on right
        # FadeIn nodes, edges, weights, labels, and content text
        self.play(
            *[Create(c) for c in nodes.values()],
            *[Write(l) for l in labels.values()],
            *[Create(e) for e in edges],
            *[Write(w) for w in weights],
            FadeIn(content_text),
            run_time=3
        )
        self.wait(2)
        # Fade out graph and content text, keep main_eq visible
        self.play(
            *[FadeOut(c) for c in nodes.values()],
            *[FadeOut(l) for l in labels.values()],
            *[FadeOut(e) for e in edges],
            *[FadeOut(w) for w in weights],
            FadeOut(content_text),
            run_time=2
        )

        # Step 3: Show transition text at bottom
        self.play(Write(transition_text), run_time=2)
        self.wait(2)

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

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