Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Python

โปรแกรมหาจำนวนเส้นทางจำกัดจากโหนดแรกถึงโหนดสุดท้ายใน Python


สมมติว่าเรามีกราฟไม่มีทิศทางมีน้ำหนักเชื่อมต่อกัน กราฟมี n โหนดตั้งชื่อ 1 ถึง n เส้นทางจากเริ่มต้นถึงสิ้นสุดคือลำดับโหนด [z0, z1, z2, ..., zk] โดย z0 เป็นโหนดเริ่มต้น zk เป็นโหนดสิ้นสุด และมีเส้นขอบระหว่าง zi และ zi+1 โดย 0 <= i <= k-1 ระยะทางของเส้นทางคือผลรวมของค่าน้ำหนักบนเส้นขอบของเส้นทาง ให้ dist(x) แทนระยะทางสั้นที่สุดจากโหนด n และโหนด x เส้นทางจำกัด (restricted path) คือเส้นทางพิเศษที่ยังสอดคล้องกับ dist(zi) > dist(zi+1) โดย 0 <= i <= k-1 เราต้องหาจำนวนเส้นทางจำกัดจากโหนด 1 ถึงโหนด n ถ้าคำตอบใหญ่เกินไป return คำตอบ modulo 10^9 + 7

เช่น ถ้าอินพุตเป็นดังภาพ ผลลัพธ์จะเป็น 3 เพราะมีเส้นทางจำกัดสามเส้นทาง: (1,2,5), (1,2,3,5), (1,3,5)

วิธีแก้ปัญหา

  • graph := adjacency list ของกราฟจาก edge list ที่กำหนด
  • paths := อาร์เรย์ขนาด (n+1) เติม 0
  • paths[n] := 1
  • dists := อาร์เรย์ขนาด (n+1) เติม -1
  • q := คิว แทรก (0, 0) เริ่มต้น
  • while q ไม่ว่าง:
    • (dist, node) := องค์ประกอบหน้าคิวและลบออก
    • ถ้า dists[node] ไม่เท่ากับ -1: ข้ามรอบถัดไป
    • dists[node] := dist
    • สำหรับแต่ละโหนดติด v และน้ำหนัก w ของ graph[node]:
      • ถ้า dists[v] เท่ากับ -1: แทรก (dist + w, v) ลง q
      • มิฉะนั้นเมื่อ dists[v] < dists[node]: paths[node] := paths[node] + paths[v]
    • ถ้า node เท่ากับ 1: return paths[node] mod 10^9+7
  • return 0

ตัวอย่าง

from collections import defaultdict
from heapq import heappop, heappush

def solve(n, edges):
    graph = defaultdict(dict)
    for u, v, w in edges:
        graph[u][v] = w
        graph[v][u] = w
    paths = [0] * (n+1)
    paths[n] = 1
    dists = [-1] * (n+1)
    q = [(0, n)]
    while q:
        dist, node = heappop(q)
        if dists[node] != -1:
            continue
        dists[node] = dist
        for v, w in graph[node].items():
            if dists[v] == -1:
                heappush(q, (dist + w, v))
            elif dists[v] < dists[node]:
                paths[node] += paths[v]
        if node == 1:
            return paths[node] % (10**9 + 7)
    return 0

n = 5
edges = [(1,2,3),(1,3,3),(2,3,1),(1,4,2),(5,2,2),(3,5,1),(5,4,10)]
print(solve(n, edges))

อินพุต

5,[(1,2,3),(1,3,3),(2,3,1),(1,4,2),(5,2,2),(3,5,1),(5,4,10)]

เอาต์พุต

3