Cod sursa(job #3335245)

Utilizator stefan_15Salcianu Stefan Alexandru stefan_15 Data 22 ianuarie 2026 00:57:04
Problema Componente tare conexe Scor 0
Compilator py Status done
Runda Arhiva educationala Marime 3.48 kb
import sys

def solve():
    # --- 1. CITIRE RAPIDA ---
    try:
        # Citim tot continutul (inputul poate fi mare)
        input_data = sys.stdin.read().split()
    except Exception:
        return

    if not input_data:
        return

    iterator = iter(input_data)
    
    try:
        n = int(next(iterator))
        m = int(next(iterator))
        
        # Initializam listele de adiacenta
        adj = [[] for _ in range(n + 1)]
        adj_rev = [[] for _ in range(n + 1)]
        
        for _ in range(m):
            u = int(next(iterator))
            v = int(next(iterator))
            adj[u].append(v)
            adj_rev[v].append(u)
            
    except StopIteration:
        return

    # --- 2. PASUL 1: DFS Iterativ pentru ordinea de finalizare ---
    # Scop: Sa umplem 'order_stack' (echivalentul lui sv/stc)
    visited = [False] * (n + 1)
    order_stack = []
    
    # Pentru DFS iterativ post-order avem nevoie sa stim unde am ramas la vecini
    # iter_state[u] = indexul urmatorului vecin de vizitat pentru nodul u
    iter_state = [0] * (n + 1)
    
    for i in range(1, n + 1):
        if not visited[i]:
            # Simulam stiva recursiva manual
            stack = [i]
            visited[i] = True
            
            while stack:
                u = stack[-1] # Ne uitam la nodul din varf
                
                # Avem vecini nevizitati?
                if iter_state[u] < len(adj[u]):
                    v = adj[u][iter_state[u]]
                    iter_state[u] += 1 # Avansam indexul pentru data viitoare
                    
                    if not visited[v]:
                        visited[v] = True
                        stack.append(v) # Intram in recursivitate (push)
                else:
                    # Toti vecinii au fost vizitati, terminam nodul u
                    stack.pop() # Iesim din recursivitate
                    order_stack.append(u) # Adaugam in lista de ordine (post-order)

    # --- 3. PASUL 2: DFS/BFS Iterativ pe graful transpus ---
    # Aici e mai simplu, nu ne trebuie post-order, doar accesibilitate
    visited_rev = [False] * (n + 1)
    solutie = []
    
    # Parcurgem stiva de la coada la cap (LIFO)
    while order_stack:
        nod_start = order_stack.pop()
        
        if not visited_rev[nod_start]:
            componenta = []
            # Facem un DFS simplu iterativ (sau BFS) pentru a colecta componenta
            stiva_comp = [nod_start]
            visited_rev[nod_start] = True
            
            while stiva_comp:
                u = stiva_comp.pop()
                componenta.append(u)
                
                for v in adj_rev[u]:
                    if not visited_rev[v]:
                        visited_rev[v] = True
                        stiva_comp.append(v)
            
            solutie.append(componenta)

    # --- 4. AFISARE ---
    # Folosim stdout.write pentru viteza maxima
    out = []
    out.append(str(len(solutie)))
    
    for comp in solutie:
        # Convertim linia in string: "1 2 3"
        out.append(" ".join(map(str, comp)))
        
    print('\n'.join(out))

if __name__ == "__main__":
    # Redirectionare intrare/iesire daca e cazul (pentru Infoarena/PbInfo sterge sau lasa comentat daca nu e nevoie)
    try:
        sys.stdin = open("ctc.in", "r")
        sys.stdout = open("ctc.out", "w")
    except FileNotFoundError:
        pass
        
    solve()