#include c_err_t c_EdgeWeightedDigraph_Init(c_EdgeWeightedDigraph_t* self, c_size_t V, c_Allocator_t* alloc) { if (!self) return C_ERR_PARAM; self->allocator = alloc ? *alloc : c_DefaultAllocator; self->V = V; self->E = 0; self->adj_list = NULL; self->edges_pool = NULL; self->edges_cap = 0; self->indegree = NULL; if (V > 0) { /* Allocate dynamic adjacency list managers matching V size */ self->adj_list = c_Allocator_Calloc(&self->allocator, V, sizeof(c_AdjList_t)); if (!self->adj_list) return C_ERR_NOMEM; for (c_size_t i = 0; i < V; ++i) { c_AdjList_Init(&self->adj_list[i],0, alloc); } /* Allocate the specialized O(1) in-degree cache array */ self->indegree = (c_size_t*)c_Allocator_Calloc(&self->allocator, V, sizeof(c_size_t)); if (!self->indegree) { c_Allocator_Free(&self->allocator, self->adj_list); self->adj_list = NULL; return C_ERR_NOMEM; } } return C_SUCCESS; } void c_EdgeWeightedDigraph_Destroy(c_EdgeWeightedDigraph_t* self) { if (!self) return; if (self->adj_list) { for (c_size_t i = 0; i < self->V; ++i) { c_UIntArray_Destroy(&self->adj_list[i]); } c_Allocator_Free(&self->allocator, self->adj_list); self->adj_list = NULL; } if (self->edges_pool) { c_Allocator_Free(&self->allocator, self->edges_pool); self->edges_pool = NULL; } if (self->indegree) { c_Allocator_Free(&self->allocator, self->indegree); self->indegree = NULL; } self->V = 0; self->E = 0; self->edges_cap = 0; c_Allocator_Destroy(&self->allocator); } c_err_t c_EdgeWeightedDigraph_AddEdge(c_EdgeWeightedDigraph_t* self, c_size_t from, c_size_t to, double weight) { if (!self || from >= self->V || to >= self->V) return C_ERR_PARAM; /* 1. Ensure the global directed edge pool has sufficient capacity */ if (self->E >= self->edges_cap) { c_size_t old_cap = self->edges_cap; c_size_t new_cap = (old_cap == 0) ? 4 : (old_cap * 2); c_DirectedEdge_t* new_pool = (c_DirectedEdge_t*)c_Allocator_Realloc( &self->allocator, self->edges_pool, old_cap * sizeof(c_DirectedEdge_t), new_cap * sizeof(c_DirectedEdge_t) ); if (!new_pool) return C_ERR_NOMEM; self->edges_pool = new_pool; self->edges_cap = new_cap; } /* 2. Populate the edge metadata inside the pool slot */ c_size_t edge_id = self->E; self->edges_pool[edge_id] = (c_DirectedEdge_t){ .from = from, .to = to, .weight = weight }; /* 3. Append the edge_id reference to the source vertex's adjacency out-list */ c_err_t err = c_AdjList_Append(&self->adj_list[from], (c_uint_t)edge_id); if (err != C_SUCCESS) return err; /* 4. Update the cached in-degree tracking array counter at the destination vertex */ self->indegree[to]++; self->E++; return C_SUCCESS; } c_err_t c_EdgeWeightedDigraph_GetEdge(c_EdgeWeightedDigraph_t* self, c_size_t edge_idx, c_DirectedEdge_t* edge) { if (!self ) return C_ERR_PARAM; /* Strict firewall boundary validation against the total allocated edge count */ if (edge_idx >= self->E) return C_ERR_OUTOFBOUND; /* Execute a fast bitwise block-copy of the edge object contents */ if (edge) { *edge = self->edges_pool[edge_idx]; } return C_SUCCESS; } c_err_t c_EdgeWeightedDigraph_RemoveEdge(c_EdgeWeightedDigraph_t* self, c_size_t edge_id) { if (!self) return C_ERR_PARAM; /* 1. Bounds check firewall validation */ if (edge_id >= self->E) return C_ERR_OUTOFBOUND; c_DirectedEdge_t* edge = &self->edges_pool[edge_id]; /* If the edge is already soft-deleted, skip to avoid double decrement corruptions */ if (edge->from == C_DIRECTED_EDGE_SENTINEL) return C_SUCCESS; c_size_t from_vertex = edge->from; c_size_t to_vertex = edge->to; /* 2. Locate and purge the edge_id reference out from the source's adj_list */ c_UIntArray_t* adj = &self->adj_list[from_vertex]; c_size_t adj_size = (c_size_t)c_UIntArray_GetSize(adj); c_bool_t found = C_FALSE; for (c_size_t i = 0; i < adj_size; ++i) { c_uint_t generic_id = 0; if (c_UIntArray_Get(adj, i, &generic_id) == C_SUCCESS) { if ((c_size_t)generic_id == edge_id) { /* Assuming your modular c_UIntArray layout supports safe positional removals */ c_UIntArray_Remove(adj, i); found = C_TRUE; break; } } } /* 3. Finalize accounting updates if the target link was successfully detached */ if (found) { /* Soft-delete the pool metadata content attributes */ edge->from = C_DIRECTED_EDGE_SENTINEL; edge->to = C_DIRECTED_EDGE_SENTINEL; edge->weight = 0.0; /* Decrement your O(1) optimized in-degree tracker */ if (self->indegree[to_vertex] > 0) { self->indegree[to_vertex]--; } } else { return C_ERR_NOTFOUND; } return C_SUCCESS; }