B - 山岳地帯の雨水シミュレーション / Rainwater Simulation in Mountainous Terrain 解説 by admin
DeepSeek V3Overview
This is a problem where we simulate water flowing between points in a mountainous region based on elevation differences, and determine the final water volume at each point after dams have been placed.
Key Observations
The crucial observation for this problem is the property that water “only flows from higher elevation points to lower elevation points.” Because of this, by processing points in order from highest to lowest elevation, we can guarantee that when processing a given point, all water inflow from higher points has already been accounted for. By fixing the processing order to descending elevation, we enable an efficient simulation.
As a naive approach, if we process all points without sorting by elevation, water flow could appear to cycle, leading to incorrect results. Additionally, if we check all adjacent points when flowing water from each point, the computational complexity becomes \(O(NM)\), which cannot be processed within the time limit under the given constraints.
Algorithm
Preprocessing:
- For each point, create a list of “downstream adjacent points” (adjacent points with strictly lower elevation) to which water can directly flow
- Calculate the “in-degree” (number of paths through which water flows into a point) for each point (though in the actual algorithm, in-degree is not used)
Determining Processing Order:
- Sort all points in descending order of elevation. Since water does not flow between points at the same elevation, the ordering among such points does not affect the result
Water Volume Simulation:
- Process each point in the sorted order
- If the point has a dam: Do nothing and retain the water volume
- If there is no dam and downstream adjacent points exist: Divide the current water volume by the number of downstream adjacent points and distribute it equally among them. Reset the point’s own water volume to 0
- If there is no dam and no downstream adjacent points exist: Retain the water volume
With this approach, by processing from higher points first, we guarantee that when processing each point, the inflow from all higher points has already been computed.
Complexity
- Time complexity: \(O(N \log N + M)\)
- \(O(N \log N)\) for sorting
- \(O(M)\) for graph construction and computing downstream adjacent points
- \(O(N + M)\) for the water volume simulation
- Space complexity: \(O(N + M)\)
- For storing the graph and various arrays
Implementation Notes
Use iterators for efficient input reading
Manage dam locations with a set for fast lookup
Be mindful of floating-point precision issues (no problem as long as results are within the tolerance specified in the problem statement)
Create an adjacency list that only stores downstream adjacent points to streamline processing
Use a lambda function during elevation-based sorting to retain point indices
Source Code
import sys
from collections import deque
def main():
data = sys.stdin.read().split()
if not data:
return
it = iter(data)
N = int(next(it)); M = int(next(it)); K = int(next(it))
H = [0] * (N+1)
for i in range(1, N+1):
H[i] = int(next(it))
W_initial = [0] * (N+1)
for i in range(1, N+1):
W_initial[i] = float(next(it))
graph = [[] for _ in range(N+1)]
for _ in range(M):
u = int(next(it)); v = int(next(it))
graph[u].append(v)
graph[v].append(u)
dam_set = set()
if K > 0:
for _ in range(K):
s = int(next(it))
dam_set.add(s)
indegree = [0] * (N+1)
adj_low = [[] for _ in range(N+1)]
for u in range(1, N+1):
for v in graph[u]:
if H[u] > H[v]:
adj_low[u].append(v)
indegree[v] += 1
order = []
for i in range(1, N+1):
order.append(i)
order.sort(key=lambda x: H[x], reverse=True)
water = W_initial[:]
for u in order:
if u in dam_set:
continue
d = len(adj_low[u])
if d == 0:
continue
flow = water[u] / d
for v in adj_low[u]:
water[v] += flow
water[u] = 0.0
result = []
for i in range(1, N+1):
result.append(str(water[i]))
print(" ".join(result))
if __name__ == "__main__":
main()
This editorial was generated by deepseekv3.
投稿日時:
最終更新: