Cod sursa(job #2792836)

Utilizator Andrei_SturzuAndrei Sturzu Andrei_Sturzu Data 2 noiembrie 2021 12:54:03
Problema Componente tare conexe Scor 0
Compilator py Status done
Runda Arhiva educationala Marime 4.38 kb
from collections import defaultdict

count = 0
result = []
components = defaultdict(list)
stack = []

class Graph:
    def __init__(self, nodes):
        self.nodes = nodes
        self.neighbours = defaultdict(list)


    def addDirectedEdge(self, u, v):
        self.neighbours[u].append(v)


    def addUndirectedEdge(self, u, v):
        self.neighbours[u].append(v)
        self.neighbours[v].append(u)


    def addTransposeEdge(self, u, v):
        self.neighbours[v].append(u)


    def deleteNodes(self, *nodes):
        for node in nodes:
            del self.neighbours[node]
            self.nodes -= 1
        return self


    def transpose(self):
        if self.nodes > 0:
            transposed_graph = defaultdict(list)
            for source, targets in self.neighbours.items():
                for target in targets:
                    transposed_graph[target].append(source)

            t = Graph(self.nodes)
            t.neighbours = transposed_graph
            return t
        else:
            return None


    def dfs(self, node, visited):
        visited[node] = True

        for i in self.neighbours[node]:
            if not visited[i]:
                self.dfs(i, visited)
        return visited


    # def SCC(self):
    #     global count
    #     if self.nodes > 0:
    #         transpose_g = self.transpose()
    #
    #         visited_g = {i: False for i in list(self.neighbours.keys())}
    #         visited_tg = {i: False for i in list(self.neighbours.keys())}
    #
    #         source = list(self.neighbours.keys())[0]
    #
    #         r1 = self.dfs(source, visited_g)
    #         r2 = transpose_g.dfs(source, visited_tg)
    #
    #         res = []
    #
    #         for i in list(self.neighbours.keys()):
    #             if r1[i] and r2[i]:
    #                 res.append(i)
    #
    #         result.append(res)
    #         count += 1
    #
    #         new_g = self.deleteNodes(*res)
    #         if new_g is not None:
    #             new_g.SCC()
    #     else:
    #         return count


    def SCC_Kosaraju(self):
        global stack, v1, v2, count

        for node in list(self.neighbours.keys()):
            if not v1[node]:
                g.dfs_Kosaraju1(node)

        stack = reversed(stack)
        for node in stack:
            if not v2[node]:
                count += 1
                g.dfs_Kosaraju2(node)

        return components

    def dfs_Kosaraju1(self, source):
        global stack
        v1[source] = True
        for node in self.neighbours[source]:
            if not v1[node]:
                self.dfs_Kosaraju1(node)
        stack.append(source)

    def dfs_Kosaraju2(self, source):
        global components
        v2[source] = True
        components[count].append(source)

        for node in self.transpose().neighbours[source]:
            if not v2[node]:
                self.dfs_Kosaraju2(node)

    # def bfs(self, s):
    #     visited = {i: False for i in list(self.neighbours.keys())}
    #
    #     queue = []
    #     cost = {i: 0 for i in list(self.neighbours.keys())}
    #
    #     queue.append(s)
    #     visited[s] = True
    #
    #     while queue:
    #         s = queue.pop(0)
    #         print(s, sep=' ')
    #         for i in self.neighbours[s]:
    #             if not visited[i]:
    #                 queue.append(i)
    #                 cost[i] = cost[s] + 1
    #                 visited[i] = True
    #
    #     for node in self.neighbours.keys():
    #         if not visited[node]:
    #             cost[node] = -1
    #
    #     return cost


file = 'ctc.in'

with open(file, 'rt') as f:
    content = f.readlines()
    content = [line.strip().split() for line in content]
    content = [[int(x) for x in line] for line in content]
    N, M = content[0][0], content[0][1]


g = Graph(N)
for edges in content[1:]:
    g.addDirectedEdge(edges[0], edges[1])


v1 = {i: False for i in list(g.neighbours.keys())}
v2 = {i: False for i in list(g.neighbours.keys())}

result = g.SCC_Kosaraju()

# print(count)
# print(result)

with open('ctc.out', 'wt') as f:
    f.write(str(count))
    f.write('\n')
    for component in result.values():
        for node in component:
            f.write(str(node))
            f.write(' ')
        f.write('\n')