สมมติว่าเรามีเมทริกซ์ไบนารี 2d โดยที่ 0 แทนเซลล์ว่างและ 1 แทนผนัง เราต้องหาจำนวนเซลล์ขั้นต่ำที่ต้องกลายเป็นกำแพงเพื่อไม่ให้มีเส้นทางระหว่างเซลล์บนซ้ายกับเซลล์ขวาล่าง เราไม่สามารถใส่กำแพงที่เซลล์บนซ้ายและเซลล์ล่างขวาได้ ขยับได้เฉพาะ ซ้าย ขวา ขึ้น ลง ไม่ใช่แนวทแยง
ดังนั้นหากอินพุตเป็นแบบ
| 0 | 0 | 0 | 0 |
| 0 | 1 | 0 | 0 |
| 0 | 1 | 1 | 0 |
| 0 | 0 | 0 | 0 |
แล้วผลลัพธ์จะเป็น 2
| 0 | 1 | 0 | 0 |
| 0 | 1 | 0 | 0 |
| 0 | 1 | 1 | 0 |
| 0 | 0 | 1 | 0 |
เพื่อแก้ปัญหานี้ เราจะทำตามขั้นตอนเหล่านี้ -
-
R :=จำนวนแถวของเมทริกซ์, C :=จำนวนคอลัมน์ของเมทริกซ์
-
เข้าชมแล้ว :=ชุดใหม่
-
tin :=แผนที่ใหม่ ต่ำ :=แผนที่ใหม่
-
ตัวจับเวลา :=0
-
bridge_pts :=ชุดใหม่
-
พาร์ :=แผนที่ใหม่
-
src :=คู่ (0, 0)
-
tgt :=คู่ (R − 1, C − 1)
-
กำหนดฟังก์ชัน dfs() นี่จะใช้เวลา v, parent
-
ทำเครื่องหมาย v ว่าเข้าชมแล้ว
-
par[v] :=parent, tin[v] :=ตัวจับเวลา, ต่ำ[v] :=ตัวจับเวลา
-
ตัวจับเวลา :=ตัวจับเวลา + 1
-
ลูก :=0
-
สำหรับแต่ละเพื่อนบ้านของ v ทำ
-
ถ้า to เหมือนกับ parent แล้ว
-
ไปทำซ้ำต่อไป
-
-
หากมีการเยี่ยมชมแล้ว
-
ต่ำ[v] :=ต่ำสุดของต่ำ[v] และ tin[to]
-
-
มิฉะนั้น
-
dfs(ถึง, v)
-
ต่ำ[v] :=ต่ำสุดของต่ำ[v] และต่ำ[ถึง]
-
ถ้า low[to]>=tin[v] และ parent ไม่ใช่ null แล้ว
-
เพิ่ม v ลงใน bridge_pts
-
-
เด็ก :=เด็ก + 1
-
-
-
ถ้าพาเรนต์เป็นโมฆะและลูก> 1 แล้ว
-
เพิ่ม v ลงใน bridge_pts
-
-
กำหนดฟังก์ชัน bfs() สิ่งนี้จะหยั่งราก
-
Q :=คิวสองสิ้นสุดพร้อมรายการที่มีรูทองค์ประกอบเดียว
-
เยี่ยมชม :=ชุดใหม่และเริ่มต้นการรูท
-
ในขณะที่ Q ไม่ว่างเปล่าให้ทำ
-
v :=องค์ประกอบสุดท้ายของ Q จากนั้นลบองค์ประกอบสุดท้ายออกจาก Q
-
ถ้า v เหมือนกับ tgt แล้ว
-
คืนค่า True
-
-
สำหรับแต่ละ w ในเพื่อนบ้านของ v ทำ
-
ถ้าไม่ได้ไปเยี่ยมแล้ว
-
ทำเครื่องหมายว่าเยี่ยมชมแล้ว
-
แทรก w ที่ด้านซ้ายของ Q
-
-
-
-
คืนค่าเท็จ
-
จากวิธีหลักให้ทำดังต่อไปนี้ -
-
dfs(src, null)
-
ถ้า tgt ไม่เท่ากัน
-
คืนค่า 0
-
-
สำหรับแต่ละคู่ (i, j) ใน bridge_pts ให้ทำ
-
เมทริกซ์[i, j] :=1
-
-
ถ้า bfs(src) เป็นจริง
-
กลับ 2
-
-
กลับ 1
ให้เราดูการใช้งานต่อไปนี้เพื่อความเข้าใจที่ดีขึ้น -
ตัวอย่าง
from collections import deque
class Solution:
def solve(self, matrix):
R = len(matrix)
C = len(matrix[0])
def get_neighbors(i, j):
for ii, jj in ((i + 1, j), (i− 1, j), (i, j + 1), (i, j − 1)):
if 0 <= ii < R and 0 <= jj < C and matrix[ii][jj] == 0:
yield ii, jj
visited = set()
tin = {}
low = {}
timer = 0
bridge_pts = set()
par = {}
src = (0, 0)
tgt = (R− 1, C− 1)
def dfs(v, parent):
nonlocal timer
visited.add(v)
par[v] = parent
tin[v] = timer
low[v] = timer
timer += 1
children = 0
for to in get_neighbors(*v):
if to == parent:
continue
if to in visited:
low[v] = min(low[v], tin[to])
else:
dfs(to, v)
low[v] = min(low[v], low[to])
if low[to] >= tin[v] and parent is not None:
bridge_pts.add(v)
children += 1
if parent is None and children > 1:
bridge_pts.add(v)
def bfs(root):
Q = deque([root])
visited = set([root])
while Q:
v = Q.pop()
if v == tgt:
return True
for w in get_neighbors(*v):
if w not in visited:
visited.add(w)
Q.appendleft(w)
return False
dfs(src, None)
if tgt not in par:
return 0
for i, j in bridge_pts:
matrix[i][j] = 1
if bfs(src):
return 2
return 1
ob = Solution()
matrix = [
[0, 0, 0, 0],
[0, 1, 0, 0],
[0, 1, 1, 0],
[0, 0, 0, 0],
]
print(ob.solve(matrix)) อินพุต
[ [0, 0, 0, 0], [0, 1, 0, 0], [0, 1, 1, 0], [0, 0, 0, 0], ]
ผลลัพธ์
2