E - 除雪車の巡回 / Snow Plow Routing Editorial by admin
DeepSeek V3Overview
This problem asks us to find the shortest route that traverses every edge of a given connected graph at least once and returns to the starting point (the Chinese Postman Problem).
Analysis
For a closed walk that traverses every edge of a graph at least once (Eulerian circuit) to exist, every vertex must have even degree (the condition for an Eulerian circuit). However, the original graph may contain vertices with odd degree.
If there are vertices with odd degree, we need to make additional traversals between those vertices. In other words, we need to add to the total weight of the original graph’s edges the cost of optimally pairing up the odd-degree vertices and traversing between them.
Since the constraints state that “the number of odd-degree vertices is at most 16,” it is efficient to precompute the shortest distances between these vertices and use bit DP to find the optimal pairing.
Algorithm
- Graph Construction: Build the graph in adjacency list form from the input
- Extracting Odd-Degree Vertices: List all vertices with odd degree
- All-Pairs Shortest Distances: Compute the shortest distances between odd-degree vertices using BFS
- Minimum Weight Perfect Matching: Compute the minimum cost of pairing the odd-degree vertices using bit DP
- Computing the Result: Output the total edge weight sum + minimum matching cost
Specifically: - If there are 0 odd-degree vertices, simply output the total edge weight sum - If there are odd-degree vertices, find the minimum cost of optimally pairing them and add it to the total sum
Complexity
- Time complexity: \(O(N + M + K^2 \cdot N + 2^K \cdot K^2)\)
- \(K\): number of odd-degree vertices (at most 16)
- Graph construction: \(O(N + M)\)
- All-pairs shortest distances: \(O(K \cdot (N + M))\)
- Bit DP: \(O(2^K \cdot K^2)\)
- Space complexity: \(O(N + M + 2^K + K^2)\)
Implementation Notes
Since there can be multiple edges, register each edge in both directions in the adjacency list
BFS is sufficient for shortest distance computation (not Dijkstra) — although weights are positive, BFS works fine
In bit DP, manage states with bitmasks and pair unpaired vertices in order
Initialize with large values (\(10^{18}\)) to prevent overflow
Source Code
import sys
from collections import deque
def main():
data = sys.stdin.read().split()
if not data:
return
n = int(data[0])
m = int(data[1])
edges = []
graph = [[] for _ in range(n+1)]
total = 0
index = 2
deg = [0] * (n+1)
for i in range(m):
u = int(data[index]); v = int(data[index+1]); w = int(data[index+2])
index += 3
edges.append((u, v, w))
graph[u].append((v, w))
graph[v].append((u, w))
deg[u] += 1
deg[v] += 1
total += w
odd_vertices = []
for i in range(1, n+1):
if deg[i] % 2 == 1:
odd_vertices.append(i)
k = len(odd_vertices)
if k == 0:
print(total)
return
dist = [[10**18] * k for _ in range(k)]
for i in range(k):
start = odd_vertices[i]
d = [10**18] * (n+1)
d[start] = 0
q = deque([start])
while q:
u = q.popleft()
for v, w in graph[u]:
if d[v] > d[u] + w:
d[v] = d[u] + w
q.append(v)
for j in range(k):
dist[i][j] = d[odd_vertices[j]]
dp = [10**18] * (1 << k)
dp[0] = 0
for mask in range(1 << k):
if dp[mask] == 10**18:
continue
i = 0
while i < k:
if mask & (1 << i):
i += 1
continue
j = i + 1
while j < k:
if mask & (1 << j):
j += 1
continue
new_mask = mask | (1 << i) | (1 << j)
cost = dp[mask] + dist[i][j]
if dp[new_mask] > cost:
dp[new_mask] = cost
j += 1
i += 1
print(total + dp[(1 << k) - 1])
if __name__ == "__main__":
main()
This editorial was generated by deepseekv3.