图算法-割点
對于無向圖,如果刪除了一 個頂點,(頂點鄰邊也刪除) 整個圖連通分量數量變化,則這個頂點稱為割點
?
?
?
# encoding = 'utf-8'import sys sys.path.append("..") from sortedcontainers import SortedSet as TreeSetclass AdjSet:def __init__(self, filename):self._filename = filenamelines = Nonewith open(filename, 'r') as f:lines = f.readlines()if not lines:raise ValueError('Expected something from input file!')# lines[0] -> V Eself._V, self._E = (int(i) for i in lines[0].split())if self._V < 0:raise ValueError('V must be non-negative')if self._E < 0:raise ValueError('E must be non-negative')# size V list of TreeSetself._adj = [TreeSet([]) for _ in range(self._V)]for each_line in lines[1:]:a, b = (int(i) for i in each_line.split())self.validate_vertex(a)self.validate_vertex(b)if a == b:raise ValueError('Self-Loop is detected!')if b in self._adj[a]:raise ValueError('Paralles edges are detected!')self._adj[a].add(b)self._adj[b].add(a)@propertydef V(self):return self._V@propertydef E(self):return self._Edef has_edge(self, v, w):self.validate_vertex(v)self.validate_vertex(w)return w in self._adj[v]def adj(self, v):self.validate_vertex(v)return self._adj[v]def degree(self, v):return len(self.adj(v))def remove_edge(self, v, w):self.validate_vertex(v)self.validate_vertex(w)if w in self._adj[v]:self._adj[v].remove(w)if v in self._adj[w]:self._adj[w].remove(v)def validate_vertex(self, v):if v < 0 or v >= self._V:raise ValueError('vertex ' + str(v) + ' is invalid')def __str__(self):res = ['V = {}, E = {}'.format(self._V, self._E)]for v in range(self._V):res.append('{}: {}'.format(v, ' '.join(str(w) for w in self._adj[v])))return '\n'.join(res)def __repr__(self):return self.__str__()def __copy__(self):return AdjSet(self._filename)class FindCutPoints:def __init__(self, G):self._G = Gself._visited = [False] * G.Vself._ord = [-1] * G.Vself._low = [- 1] * G.Vself._cnt = 0self._res = set()for v in range(G.V):if not self._visited[v]:self._dfs(v, v)def _dfs(self, v, parent):self._visited[v] = Trueself._ord[v] = self._cntself._low[v] = self._ord[v]self._cnt += 1child = 0for w in self._G.adj(v):if not self._visited[w]:self._dfs(w, v)self._low[v] = min(self._low[v], self._low[w])if v != parent and self._low[w] >= self._ord[v]:self._res.add(v)child += 1if v == parent and child > 1:self._res.add(v)elif w != parent:self._low[v] = min(self._low[v], self._low[w])@propertydef result(self):return list(self._res)if __name__ == '__main__':filename = 'g.txt'g = AdjSet(filename)find_cut_points = FindCutPoints(g)print(find_cut_points.result)總結
- 上一篇: 图论算法-图论的表示、分类及基本概念(系
- 下一篇: 技术痴迷少年