from typing import List, Tuple, Dict, Set, TYPE_CHECKING

if TYPE_CHECKING:
    pass

class Edge:
    to: int
    weight: float

class IMGraphCpp:
    num_nodes: int
    num_edges: int
    directed: bool
    edges: Dict[Tuple[int, int], float]
    
    def __init__(self, num_nodes: int, edges: List[Tuple[int, int]], weights: List[float] = ..., directed: bool = True) -> None: ...
    
    def add_edge(self, u: int, v: int, w: float = 1.0) -> None: ...
    
    def add_edges(self, edges: List[Tuple[int, int]], weights: List[float] = ...) -> None: ...
    
    def update_edge_weight(self, u: int, v: int, w: float) -> None: ...
    
    def remove_edge(self, u: int, v: int) -> None: ...
    
    def remove_edges(self, edges: List[Tuple[int, int]]) -> None: ...
    
    def out_neighbors(self, u: int) -> List[Edge]: ...
    
    def in_neighbors(self, u: int) -> List[int]: ...
    
    def out_degree(self, u: int) -> int: ...
    
    def in_degree(self, u: int) -> int: ...
    
    def degree(self, u: int) -> int: ...
    
    def get_all_degrees(self) -> List[int]: ...
    
    def get_all_in_degrees(self) -> List[int]: ...
    
    def get_all_out_degrees(self) -> List[int]: ...
    
    def batch_out_degree(self, nodes: List[int]) -> List[int]: ...
    
    def batch_in_degree(self, nodes: List[int]) -> List[int]: ...
    
    def batch_degree(self, nodes: List[int]) -> List[int]: ...
    
    def batch_out_neighbors(self, nodes: List[int]) -> List[List[Tuple[int, float]]]: ...
    
    def batch_get_edge_weight(self, edges: List[Tuple[int, int]]) -> List[float]: ...
    
    def get_adj_list(self) -> List[List[Edge]]: ...
    
    def get_adj_matrix(self) -> List[List[float]]: ...
    
    def get_adj_matrix_sparse(self) -> List[Tuple[int, int, float]]: ...
    
    def get_edge_weight(self, u: int, v: int) -> float: ...
    
    def __repr__(self) -> str: ...
