Data update
This commit is contained in:
parent
4d5544505c
commit
4924dd0264
3073 changed files with 55820 additions and 4408 deletions
83
Task/Tarjan/JavaScript/tarjan.js
Normal file
83
Task/Tarjan/JavaScript/tarjan.js
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
class Graph {
|
||||
constructor(size) {
|
||||
this.adjacencyLists = [];
|
||||
this.vertices = [];
|
||||
this.index = 0;
|
||||
this.stack = [];
|
||||
this.numbers = new Map();
|
||||
this.lowlinks = new Map();
|
||||
this.stronglyConnectedComponents = [];
|
||||
|
||||
for (let i = 0; i < size; i++) {
|
||||
this.vertices.push(i);
|
||||
this.adjacencyLists.push(new Set());
|
||||
}
|
||||
}
|
||||
|
||||
addDirectedEdge(from, to) {
|
||||
this.adjacencyLists[from].add(to);
|
||||
}
|
||||
|
||||
getSCC() {
|
||||
for (const vertex of this.vertices) {
|
||||
if (!this.numbers.has(vertex)) {
|
||||
this.stronglyConnect(vertex);
|
||||
}
|
||||
}
|
||||
|
||||
return this.stronglyConnectedComponents;
|
||||
}
|
||||
|
||||
stronglyConnect(vertex) {
|
||||
this.numbers.set(vertex, this.index);
|
||||
this.lowlinks.set(vertex, this.index);
|
||||
this.index += 1;
|
||||
this.stack.push(vertex);
|
||||
|
||||
for (const adjacent of this.adjacencyLists[vertex]) {
|
||||
if (!this.numbers.has(adjacent)) {
|
||||
this.stronglyConnect(adjacent);
|
||||
this.lowlinks.set(vertex, Math.min(this.lowlinks.get(vertex), this.lowlinks.get(adjacent)));
|
||||
} else if (this.stack.includes(adjacent)) {
|
||||
this.lowlinks.set(vertex, Math.min(this.lowlinks.get(vertex), this.numbers.get(adjacent)));
|
||||
}
|
||||
}
|
||||
|
||||
if (this.lowlinks.get(vertex) === this.numbers.get(vertex)) {
|
||||
const stronglyConnectedComponent = new Set();
|
||||
let top;
|
||||
do {
|
||||
top = this.stack.pop();
|
||||
stronglyConnectedComponent.add(top);
|
||||
} while (top !== vertex);
|
||||
|
||||
this.stronglyConnectedComponents.push(stronglyConnectedComponent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Main function equivalent
|
||||
function main() {
|
||||
const graph = new Graph(8);
|
||||
|
||||
graph.addDirectedEdge(0, 1);
|
||||
graph.addDirectedEdge(1, 2);
|
||||
graph.addDirectedEdge(1, 7);
|
||||
graph.addDirectedEdge(2, 3);
|
||||
graph.addDirectedEdge(2, 6);
|
||||
graph.addDirectedEdge(3, 4);
|
||||
graph.addDirectedEdge(4, 2);
|
||||
graph.addDirectedEdge(4, 5);
|
||||
graph.addDirectedEdge(6, 3);
|
||||
graph.addDirectedEdge(6, 5);
|
||||
graph.addDirectedEdge(7, 0);
|
||||
graph.addDirectedEdge(7, 6);
|
||||
|
||||
console.log("The strongly connected components are: ");
|
||||
for (const component of graph.getSCC()) {
|
||||
console.log(component);
|
||||
}
|
||||
}
|
||||
|
||||
// Run the main function
|
||||
main();
|
||||
200
Task/Tarjan/Zig/tarjan.zig
Normal file
200
Task/Tarjan/Zig/tarjan.zig
Normal file
|
|
@ -0,0 +1,200 @@
|
|||
const std = @import("std");
|
||||
const ArrayList = std.ArrayList;
|
||||
const HashMap = std.HashMap;
|
||||
const print = std.debug.print;
|
||||
const Allocator = std.mem.Allocator;
|
||||
|
||||
// Simple graph representation using adjacency lists
|
||||
const Graph = struct {
|
||||
neighbors: ArrayList(ArrayList(usize)),
|
||||
allocator: Allocator,
|
||||
|
||||
const Self = @This();
|
||||
|
||||
pub fn init(allocator: Allocator, size: usize) !Self {
|
||||
var neighbors = ArrayList(ArrayList(usize)).init(allocator);
|
||||
try neighbors.ensureTotalCapacity(size);
|
||||
|
||||
for (0..size) |_| {
|
||||
try neighbors.append(ArrayList(usize).init(allocator));
|
||||
}
|
||||
|
||||
return Self{
|
||||
.neighbors = neighbors,
|
||||
.allocator = allocator,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn deinit(self: *Self) void {
|
||||
for (self.neighbors.items) |*neighbor_list| {
|
||||
neighbor_list.deinit();
|
||||
}
|
||||
self.neighbors.deinit();
|
||||
}
|
||||
|
||||
pub fn addEdge(self: *Self, from: usize, to: usize) !void {
|
||||
std.debug.assert(to < self.len());
|
||||
try self.neighbors.items[from].append(to);
|
||||
}
|
||||
|
||||
pub fn addEdges(self: *Self, from: usize, to: []const usize) !void {
|
||||
const limit = self.len();
|
||||
for (to) |vertex| {
|
||||
std.debug.assert(vertex < limit);
|
||||
try self.neighbors.items[from].append(vertex);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn getEdges(self: *const Self, vertex: usize) []const usize {
|
||||
return self.neighbors.items[vertex].items;
|
||||
}
|
||||
|
||||
pub fn isEmpty(self: *const Self) bool {
|
||||
return self.neighbors.items.len == 0;
|
||||
}
|
||||
|
||||
pub fn len(self: *const Self) usize {
|
||||
return self.neighbors.items.len;
|
||||
}
|
||||
};
|
||||
|
||||
const VertexState = struct {
|
||||
index: usize,
|
||||
low_link: usize,
|
||||
on_stack: bool,
|
||||
};
|
||||
|
||||
const Tarjan = struct {
|
||||
graph: *const Graph,
|
||||
index: usize,
|
||||
stack: ArrayList(usize),
|
||||
state: ArrayList(VertexState),
|
||||
components: ArrayList(ArrayList(usize)),
|
||||
allocator: Allocator,
|
||||
|
||||
const Self = @This();
|
||||
const INVALID_INDEX: usize = std.math.maxInt(usize);
|
||||
|
||||
pub fn init(allocator: Allocator, graph: *const Graph) !Self {
|
||||
var state = ArrayList(VertexState).init(allocator);
|
||||
try state.ensureTotalCapacity(graph.len());
|
||||
|
||||
for (0..graph.len()) |_| {
|
||||
try state.append(VertexState{
|
||||
.index = INVALID_INDEX,
|
||||
.low_link = INVALID_INDEX,
|
||||
.on_stack = false,
|
||||
});
|
||||
}
|
||||
|
||||
return Self{
|
||||
.graph = graph,
|
||||
.index = 0,
|
||||
.stack = ArrayList(usize).init(allocator),
|
||||
.state = state,
|
||||
.components = ArrayList(ArrayList(usize)).init(allocator),
|
||||
.allocator = allocator,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn deinit(self: *Self) void {
|
||||
for (self.components.items) |*component| {
|
||||
component.deinit();
|
||||
}
|
||||
self.components.deinit();
|
||||
self.stack.deinit();
|
||||
self.state.deinit();
|
||||
}
|
||||
|
||||
pub fn walk(allocator: Allocator, graph: *const Graph) !ArrayList(ArrayList(usize)) {
|
||||
var tarjan = try Self.init(allocator, graph);
|
||||
defer tarjan.deinit();
|
||||
|
||||
return try tarjan.visitAll();
|
||||
}
|
||||
|
||||
fn visitAll(self: *Self) !ArrayList(ArrayList(usize)) {
|
||||
for (0..self.graph.len()) |vertex| {
|
||||
if (self.state.items[vertex].index == INVALID_INDEX) {
|
||||
try self.visit(vertex);
|
||||
}
|
||||
}
|
||||
|
||||
// Move components out to avoid double-free
|
||||
var result = ArrayList(ArrayList(usize)).init(self.allocator);
|
||||
try result.ensureTotalCapacity(self.components.items.len);
|
||||
|
||||
for (self.components.items) |component| {
|
||||
try result.append(component);
|
||||
}
|
||||
|
||||
// Clear the original components to avoid double-free
|
||||
self.components.clearRetainingCapacity();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
fn visit(self: *Self, v: usize) !void {
|
||||
self.state.items[v].index = self.index;
|
||||
self.state.items[v].low_link = self.index;
|
||||
self.index += 1;
|
||||
try self.stack.append(v);
|
||||
self.state.items[v].on_stack = true;
|
||||
|
||||
for (self.graph.getEdges(v)) |w| {
|
||||
if (self.state.items[w].index == INVALID_INDEX) {
|
||||
try self.visit(w);
|
||||
const w_low_link = self.state.items[w].low_link;
|
||||
self.state.items[v].low_link = @min(self.state.items[v].low_link, w_low_link);
|
||||
} else if (self.state.items[w].on_stack) {
|
||||
const w_index = self.state.items[w].index;
|
||||
self.state.items[v].low_link = @min(self.state.items[v].low_link, w_index);
|
||||
}
|
||||
}
|
||||
|
||||
if (self.state.items[v].low_link == self.state.items[v].index) {
|
||||
var component = ArrayList(usize).init(self.allocator);
|
||||
|
||||
while (true) {
|
||||
const w = self.stack.pop().?;
|
||||
self.state.items[w].on_stack = false;
|
||||
try component.append(w);
|
||||
if (w == v) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
try self.components.append(component);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
pub fn main() !void {
|
||||
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
||||
defer _ = gpa.deinit();
|
||||
const allocator = gpa.allocator();
|
||||
|
||||
var graph = try Graph.init(allocator, 8);
|
||||
defer graph.deinit();
|
||||
|
||||
try graph.addEdge(0, 1);
|
||||
try graph.addEdge(2, 0);
|
||||
try graph.addEdges(5, &[_]usize{ 2, 6 });
|
||||
try graph.addEdge(6, 5);
|
||||
try graph.addEdge(1, 2);
|
||||
try graph.addEdges(3, &[_]usize{ 1, 2, 4 });
|
||||
try graph.addEdges(4, &[_]usize{ 5, 3 });
|
||||
try graph.addEdges(7, &[_]usize{ 4, 7, 6 });
|
||||
|
||||
var components = try Tarjan.walk(allocator, &graph);
|
||||
defer {
|
||||
for (components.items) |*component| {
|
||||
component.deinit();
|
||||
}
|
||||
components.deinit();
|
||||
}
|
||||
|
||||
for (components.items) |component| {
|
||||
print("{any}\n", .{component.items});
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue