Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Program to find out the minimum path to deliver all letters in Python
Suppose there are n cities connected with n-1 roads, forming a tree structure where any city can be reached from any other city. A postal worker needs to deliver k letters daily to different destination cities. We need to find the minimum distance the worker must travel to deliver all letters, starting from any city.
Problem Understanding
Given a tree of cities and a list of delivery destinations, we need to find the shortest path that visits all destination cities. The key insight is that in a tree, we need to traverse edges optimally ? some edges might be traversed twice (going and returning), but we can save distance by ending at an optimal endpoint.
Algorithm Approach
The solution uses a tree DP approach where we:
- Calculate the total cost if we traverse all necessary edges twice
- Find the maximum distance we can save by not returning on the longest path
- The answer is:
2 × total_edges_cost - max_saved_distance
Implementation
import sys
from math import inf as INF
sys.setrecursionlimit(10**5 + 5)
def depth_search(node, parent):
global SUM, MAX
d1 = -INF # Longest path from this node
d2 = -INF # Second longest path from this node
for neighbor, weight in adj_list[node]:
if neighbor != parent:
# Get the longest path from child + edge weight
child_path = depth_search(neighbor, node) + weight
# Update two longest paths
if child_path > d1:
d2 = d1
d1 = child_path
elif child_path > d2:
d2 = child_path
# Update count of delivery cities in subtree
delivery_count[node] += delivery_count[neighbor]
# If child subtree has some (but not all) deliveries,
# we must traverse this edge
if 0 < delivery_count[neighbor] < k:
SUM += weight
# Update maximum path we can save
if d1 > 0:
MAX = max(MAX, d1 + d2) # Path through this node
if d2 > 0 and has_delivery[node]:
MAX = max(MAX, d2) # Path ending at this node
# If this node needs delivery, ensure we return valid path
if has_delivery[node]:
d2 = max(0, d2)
return d2
def solve(nodes, delivery_cities, roads):
global k, delivery_count, has_delivery, adj_list, SUM, MAX
k = len(delivery_cities)
adj_list = {}
delivery_count = [0] * (nodes + 5)
has_delivery = [0] * (nodes + 5)
# Mark delivery cities
for city in delivery_cities:
delivery_count[city] = 1
has_delivery[city] = 1
# Build adjacency list
for road in roads:
x, y, cost = road
if x not in adj_list:
adj_list[x] = []
if y not in adj_list:
adj_list[y] = []
adj_list[x].append([y, cost])
adj_list[y].append([x, cost])
SUM = 0 # Total edge cost for necessary edges
MAX = 0 # Maximum distance we can save
depth_search(1, 1)
# Total cost = 2 * (necessary edges) - (longest path we don't return)
return SUM * 2 - MAX
# Test the solution
result = solve(5, [1, 2, 4], [(1,2,1), (2,3,2), (2,4,3), (1,5,1)])
print("Minimum distance:", result)
Minimum distance: 4
How It Works
For the given example with delivery cities [1, 2, 4]:
- The worker must visit edges connecting these cities
- Optimal strategy: start at city 1, go to 2 (cost 1), then to 4 (cost 3)
- Total distance: 1 + 3 = 4
- Alternative paths would cost more due to backtracking
Key Points
- Tree Property: n cities with n-1 roads form a tree structure
- Optimal Path: Visit all delivery cities with minimum backtracking
- DP Approach: Calculate longest paths to minimize return trips
Conclusion
This solution efficiently finds the minimum delivery path using tree DP. The algorithm calculates necessary edge traversals and optimizes by avoiding returns on the longest path, achieving optimal delivery routes.
