C - ネットワークの通信コスト / Network Communication Cost 解説 by admin
Claude 4.6 Opus (Thinking)Overview
This is a simulation problem on a tree-structured network where you switch the operating modes of relay stations and update correction parameters, while calculating the communication cost along the path between two specified points.
Analysis
- In a tree structure, the path between any two vertices \(A\) and \(B\) is uniquely determined. We simply need to find that path and calculate the communication cost.
- Since the constraints are relatively small with \(N \leq 5000\) and \(Q \leq 5000\), recomputing the path for each query is fast enough.
- The effective coordinates of each relay station are either \((X_i, Y_i)\) or \((-X_i, -Y_i)\) depending on the operating mode, so we need to reference the mode at the time of the query for computation.
- Advanced data structures (such as Heavy-Light Decomposition) are unnecessary; a straightforward approach of finding the path with BFS and summing up the cost for each edge is sufficient.
Algorithm
Reading input and initialization: Read the coordinates of each relay station and the tree edge information. Initialize all relay stations to normal mode with \(S = 0\).
Operation 1 (
1 C): Toggle the operating mode flag of relay station \(C\).Operation 2 (
2 W): Add \(W\) to \(S\).Operation 3 (
3 A B): Compute the answer with the following procedure:- If \(A = B\), there is 1 relay station on the path and 0 links, so the answer is \(S \times 1 = S\).
- If \(A \neq B\), find the path from \(A\) to \(B\) using BFS. Specifically, record parent information during BFS and reconstruct the path by tracing parents from \(B\) back to \(A\).
- For each adjacent pair of relay stations \((u, v)\) on the path, compute the Manhattan distance \(|X'_u - X'_v| + |Y'_u - Y'_v|\) using the effective coordinates based on the current operating mode, and take the total sum.
- The final answer is “total communication cost \(+\) \(S \times\) number of relay stations on the path”.
Complexity
- Time complexity: \(O(Q \times N)\)
- Each operation 3 performs BFS (\(O(N)\)) and cost calculation along the path (\(O(N)\)). Operations 1 and 2 are \(O(1)\).
- In the worst case with \(Q = 5000\) and \(N = 5000\), the computation is approximately \(2.5 \times 10^7\).
- Space complexity: \(O(N)\)
- \(O(N)\) for the adjacency list, parent array, path array, etc.
Implementation Notes
Manage a parent array
parentduring BFS, recordingparent[v] = u(the vertex \(u\) that discovered \(v\)). Setparent[A] = Afor the starting point \(A\) to distinguish it from unvisited vertices.Path reconstruction is done by tracing
parentfrom \(B\) until reaching \(A\).Since the output value can be negative, use a signed integer type (
long long).To avoid overflow from multiplication of \(S\) values and coordinate values, perform calculations using
long longtype (\(S\) can be up to approximately \(5000 \times 10^5 = 5 \times 10^8\), and its product with the number of nodes can reach approximately \(2.5 \times 10^{12}\)).Source Code
#include <bits/stdc++.h>
using namespace std;
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int N, Q;
cin >> N >> Q;
vector<long long> X(N+1), Y(N+1);
for (int i = 1; i <= N; i++) {
cin >> X[i] >> Y[i];
}
vector<vector<int>> adj(N+1);
for (int j = 0; j < N-1; j++) {
int u, v;
cin >> u >> v;
adj[u].push_back(v);
adj[v].push_back(u);
}
vector<bool> inverted(N+1, false);
long long S = 0;
vector<int> parent(N+1);
for (int q = 0; q < Q; q++) {
int type;
cin >> type;
if (type == 1) {
int C;
cin >> C;
inverted[C] = !inverted[C];
} else if (type == 2) {
long long W;
cin >> W;
S += W;
} else {
int A, B;
cin >> A >> B;
if (A == B) {
cout << S << "\n";
continue;
}
// BFS from A to find path to B
fill(parent.begin(), parent.end(), -1);
parent[A] = A;
queue<int> bfs;
bfs.push(A);
while (!bfs.empty()) {
int u = bfs.front();
bfs.pop();
if (u == B) break;
for (int v : adj[u]) {
if (parent[v] == -1) {
parent[v] = u;
bfs.push(v);
}
}
}
// Trace path from B to A
vector<int> path;
int cur = B;
while (cur != A) {
path.push_back(cur);
cur = parent[cur];
}
path.push_back(A);
// Compute answer
long long cost = 0;
int num_nodes = (int)path.size();
for (int i = 0; i + 1 < num_nodes; i++) {
int u = path[i], v = path[i+1];
long long xu = inverted[u] ? -X[u] : X[u];
long long yu = inverted[u] ? -Y[u] : Y[u];
long long xv = inverted[v] ? -X[v] : X[v];
long long yv = inverted[v] ? -Y[v] : Y[v];
cost += abs(xu - xv) + abs(yu - yv);
}
cost += S * (long long)num_nodes;
cout << cost << "\n";
}
}
return 0;
}
This editorial was generated by claude4.6opus-thinking.
投稿日時:
最終更新: