Skip to content

Commit 53cd89b

Browse files
committed
增加桥和割点的说明和编程实现,以及非遍历树边,前向树,后向树的简单介绍(add bridge and cut point,etc)
1 parent 879d9d9 commit 53cd89b

10 files changed

+481
-0
lines changed

Bridges/__init__.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
"""
2+
@author: Alex
3+
@contact: 1272296763@qq.com or jakinmili@gmail.com
4+
@file: __init__.py.py
5+
@time: 2019/11/13 20:54
6+
"""
7+

Bridges/findBridges.py

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
"""
2+
@author: Alex
3+
@contact: 1272296763@qq.com or jakinmili@gmail.com
4+
@file: findBridges.py
5+
@time: 2019/10/20 19:12
6+
"""
7+
class findBridges:
8+
9+
def __init__(self, filename):
10+
self.V = 0 # 顶点数
11+
self.E = 0 # 边数
12+
self.adj = None
13+
14+
15+
16+
with open(filename) as f:
17+
line_num = 0 # 第一行是顶点数和边数
18+
for line in f:
19+
if line_num == 0:
20+
v, e = line.strip().split()
21+
self.V = int(v)
22+
self.E = int(e)
23+
self.adj = [[] for i in range(self.V)] # 创建二维数组即邻接表
24+
else:
25+
# 读取边 写入邻接表
26+
v1, v2 = line.strip().split()
27+
# 转化为整数
28+
v1 = int(v1)
29+
v2 = int(v2)
30+
self.adj[v1].append(v2)
31+
self.adj[v2].append(v1)
32+
line_num += 1
33+
34+
self.__visited = [False for i in range(self.V)]
35+
self.__ord = [0 for i in range(self.V)]
36+
self.__low = [0 for i in range(self.V)]
37+
self.__cnt = 0
38+
self.res = []
39+
40+
41+
# 各个联通分量寻找桥
42+
for v in range(self.V):
43+
if self.__visited[v] == False:
44+
self.graphDFS(v, v)
45+
46+
def get_graph_information(self):
47+
"""
48+
打印图的邻接表
49+
:return:
50+
"""
51+
print("V={}, E={}".format(self.V, self.E))
52+
for i, v in enumerate(self.adj):
53+
print("{} : {}".format(i, v))
54+
55+
def validateVertex(self, v):
56+
"""
57+
验证顶点取值
58+
:param v:
59+
:return:
60+
"""
61+
if v<0 or v>=self.V:
62+
raise ValueError("v值超出范围")
63+
64+
def hasEdge(self, v, w):
65+
"""
66+
判断两个顶点是否存在
67+
:param v: 第一个顶点
68+
:param w: 第二个顶点
69+
:return: true or false
70+
"""
71+
self.validateVertex(v)
72+
self.validateVertex(w)
73+
return w in self.adj[v]
74+
75+
def degree(self, v):
76+
"""
77+
求某个顶点的度
78+
:param v:
79+
:return:
80+
"""
81+
self.validateVertex(v)
82+
return len(self.adj[v])
83+
84+
85+
def graphDFS(self, v, parent):
86+
87+
# 标记v顶点已经遍历过了
88+
self.__visited[v] = True
89+
self.__ord[v] = self.__cnt
90+
self.__low[v] = self.__ord[v]
91+
self.__cnt+=1
92+
# 添加
93+
for w in self.adj[v]:
94+
if self.__visited[w] == False:
95+
self.graphDFS(w, v)
96+
self.__low[v] = min(self.__low[v], self.__low[w])
97+
if self.__low[w] > self.__ord[v]:
98+
# v-w是桥
99+
self.res.append("{}-{}".format(v,w))
100+
101+
elif w != parent:
102+
self.__low[v] = min(self.__low[v], self.__low[w])
103+
104+
def findBridges(self):
105+
print("该联通分量有存在桥的有:", self.res)
106+
107+
if __name__ == '__main__':
108+
fb = findBridges("../g_bridges2.txt")
109+
fb.get_graph_information()
110+
fb.findBridges()
111+
112+
fb1 = findBridges("../tree.txt")
113+
fb1.get_graph_information()
114+
fb1.findBridges()

Bridges/findCutPoint.py

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
"""
2+
@author: Alex
3+
@contact: 1272296763@qq.com or jakinmili@gmail.com
4+
@file: findCutPoint.py
5+
@time: 2019/10/20 19:12
6+
"""
7+
class findCutPoint:
8+
9+
def __init__(self, filename):
10+
self.V = 0 # 顶点数
11+
self.E = 0 # 边数
12+
self.adj = None
13+
14+
15+
16+
with open(filename) as f:
17+
line_num = 0 # 第一行是顶点数和边数
18+
for line in f:
19+
if line_num == 0:
20+
v, e = line.strip().split()
21+
self.V = int(v)
22+
self.E = int(e)
23+
self.adj = [[] for i in range(self.V)] # 创建二维数组即邻接表
24+
else:
25+
# 读取边 写入邻接表
26+
v1, v2 = line.strip().split()
27+
# 转化为整数
28+
v1 = int(v1)
29+
v2 = int(v2)
30+
self.adj[v1].append(v2)
31+
self.adj[v2].append(v1)
32+
line_num += 1
33+
34+
self.__visited = [False for i in range(self.V)]
35+
self.__ord = [0 for i in range(self.V)]
36+
self.__low = [0 for i in range(self.V)]
37+
self.__cnt = 0
38+
self.res = set()
39+
40+
41+
# 各个联通分量寻找桥
42+
for v in range(self.V):
43+
if self.__visited[v] == False:
44+
self.graphDFS(v, v)
45+
46+
def get_graph_information(self):
47+
"""
48+
打印图的邻接表
49+
:return:
50+
"""
51+
print("V={}, E={}".format(self.V, self.E))
52+
for i, v in enumerate(self.adj):
53+
print("{} : {}".format(i, v))
54+
55+
def validateVertex(self, v):
56+
"""
57+
验证顶点取值
58+
:param v:
59+
:return:
60+
"""
61+
if v<0 or v>=self.V:
62+
raise ValueError("v值超出范围")
63+
64+
def hasEdge(self, v, w):
65+
"""
66+
判断两个顶点是否存在
67+
:param v: 第一个顶点
68+
:param w: 第二个顶点
69+
:return: true or false
70+
"""
71+
self.validateVertex(v)
72+
self.validateVertex(w)
73+
return w in self.adj[v]
74+
75+
def degree(self, v):
76+
"""
77+
求某个顶点的度
78+
:param v:
79+
:return:
80+
"""
81+
self.validateVertex(v)
82+
return len(self.adj[v])
83+
84+
85+
def graphDFS(self, v, parent):
86+
87+
# 标记v顶点已经遍历过了
88+
self.__visited[v] = True
89+
self.__ord[v] = self.__cnt
90+
self.__low[v] = self.__ord[v]
91+
self.__cnt+=1
92+
93+
child = 0
94+
# 添加
95+
for w in self.adj[v]:
96+
if self.__visited[w] == False:
97+
self.graphDFS(w, v)
98+
self.__low[v] = min(self.__low[v], self.__low[w])
99+
100+
# 割点检测
101+
if v != parent and self.__low[w] >= self.__ord[v]:
102+
self.res.add(v)
103+
104+
child += 1
105+
106+
if v == parent and child>1: # 如果是根节点
107+
self.res.add(v)
108+
109+
elif w != parent:
110+
self.__low[v] = min(self.__low[v], self.__low[w])
111+
112+
def findCutPoint(self):
113+
print("该联通分量有存在割点的有:", self.res)
114+
115+
if __name__ == '__main__':
116+
fb = findCutPoint("../g_bridges2.txt")
117+
fb.get_graph_information()
118+
fb.findCutPoint()
119+
120+
fb1 = findCutPoint("../tree.txt")
121+
fb1.get_graph_information()
122+
fb1.findCutPoint()

Floodfill/Solution.py

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
"""
2+
@author: Alex
3+
@contact: 1272296763@qq.com or jakinmili@gmail.com
4+
@file: Solution.py
5+
@time: 2019/10/27 13:38
6+
"""
7+
8+
class Solution(object):
9+
10+
def __init__(self):
11+
self.__R = 0 # row
12+
self.__C = 0 # colum
13+
self.dirs = [
14+
[-1, 0], [0, 1], [1, 0], [0, -1]
15+
]
16+
self.visited = []
17+
self.grid = []
18+
self.G = []
19+
20+
def maxAreaOfIsland(self, grid):
21+
"""
22+
:type grid: List[List[int]]
23+
:rtype: int
24+
"""
25+
if grid == None: return 0
26+
self.__R = len(grid)
27+
if self.__R == 0: return 0
28+
self.__C = len(grid[0])
29+
if self.__C == 0: return 0
30+
self.grid = grid
31+
32+
self.G = self.constructGraph()
33+
# 对每一个陆地进行遍历
34+
res = 0
35+
self.visited = [False for i in range(len(self.G))]
36+
for v in range(len(self.G)):
37+
x = int(v / self.__C)
38+
y = v % self.__C
39+
if self.grid[x][y] == 1 and self.visited[v] == False:
40+
res = max(res, self.dfs(v))
41+
return res
42+
43+
def dfs(self, v):
44+
self.visited[v] = True
45+
res = 1
46+
for w in self.G[v]:
47+
if self.visited[w] == False:
48+
res += self.dfs(w)
49+
return res
50+
51+
52+
def constructGraph(self):
53+
g = [[] for i in range(self.__R * self.__C)]
54+
55+
# 二维转一维
56+
for v in range(len(g)):
57+
x = int(v / self.__C)
58+
y = v % self.__C
59+
# 一维表中某个位置计算出的(x, y) 代表 二维表中的坐标
60+
if self.grid[x][y] == 1:
61+
# 对(x, y)四个方向都进行观察,看看是否有陆地
62+
# 如果有,在邻接表中相应位置 增加一条边
63+
for d in self.dirs:
64+
next_x = x + d[0]
65+
next_y = y + d[1]
66+
if self.inArea(next_x, next_y) and self.grid[next_x][next_y] :
67+
next = next_x * self.__C + next_y
68+
g[v].append(next)
69+
g[next].append(v)
70+
return g
71+
72+
def inArea(self, x, y):
73+
return x >= 0 and x < self.__R and y >= 0 and y < self.__C
74+
75+
76+
77+
if __name__ == '__main__':
78+
obj = Solution()
79+
print(obj.maxAreaOfIsland([[0,0,1,0,0,0,0,1,0,0,0,0,0],
80+
[0,0,0,0,0,0,0,1,1,1,0,0,0],
81+
[0,1,1,0,1,0,0,0,0,0,0,0,0],
82+
[0,1,0,0,1,1,0,0,1,0,1,0,0],
83+
[0,1,0,0,1,1,0,0,1,1,1,0,0],
84+
[0,0,0,0,0,0,0,0,0,0,1,0,0],
85+
[0,0,0,0,0,0,0,1,1,1,0,0,0],
86+
[0,0,0,0,0,0,0,1,1,0,0,0,0]]))

0 commit comments

Comments
 (0)