Π‘ΡΡΠ»ΠΊΠ° Π½Π° Π·Π°Π΄Π°ΡΡ β 3108. Minimum Cost Walk in Weighted Graph.
π ΠΠΏΠΈΡΠ°Π½ΠΈΠ΅ Π·Π°Π΄Π°ΡΠΈ
- ΠΠ°Π½ Π½Π΅ΠΎΡΠΈΠ΅Π½ΡΠΈΡΠΎΠ²Π°Π½Π½ΡΠΉ Π²Π·Π²Π΅ΡΠ΅Π½Π½ΡΠΉ Π³ΡΠ°Ρ Ρ
n
Π²Π΅ΡΡΠΈΠ½Π°ΠΌΠΈ ΠΈ m
ΡΡΠ±ΡΠ°ΠΌΠΈ.
- ΠΠ°ΠΆΠ΄ΠΎΠ΅ ΡΠ΅Π±ΡΠΎ ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π»Π΅Π½ΠΎ ΡΡΠΎΠΉΠΊΠΎΠΉ
[u, v, w]
, ΠΎΠ·Π½Π°ΡΠ°ΡΡΠ΅ΠΉ, ΡΡΠΎ ΡΡΡΠ΅ΡΡΠ²ΡΠ΅Ρ ΡΠ΅Π±ΡΠΎ ΠΌΠ΅ΠΆΠ΄Ρ u
ΠΈ v
Ρ Π²Π΅ΡΠΎΠΌ w
.
- ΠΠΏΡΠ΅Π΄Π΅Π»ΠΈΠΌ ΡΡΠΎΠΈΠΌΠΎΡΡΡ ΠΏΡΡΠΈ ΠΌΠ΅ΠΆΠ΄Ρ Π΄Π²ΡΠΌΡ Π²Π΅ΡΡΠΈΠ½Π°ΠΌΠΈ ΠΊΠ°ΠΊ Π±ΠΈΡΠΎΠ²ΠΎΠ΅
AND
Π²ΡΠ΅Ρ
ΡΡΠ±Π΅Ρ, ΠΏΡΠΎΠΉΠ΄Π΅Π½Π½ΡΡ
Π½Π° ΠΏΡΡΠΈ (Π²Π΅ΡΡΠΈΠ½Π°ΠΌ Π² ΡΠ°ΠΊΠΎΠΌ ΠΏΡΡΠΈ ΡΠ°Π·ΡΠ΅ΡΠ΅Π½ΠΎ ΠΏΠΎΠ²ΡΠΎΡΡΡΡΡΡ).
- ΠΠ»Ρ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ Π·Π°ΠΏΡΠΎΡΠ°
[s, t]
ΡΡΠ΅Π±ΡΠ΅ΡΡΡ Π½Π°ΠΉΡΠΈ ΠΌΠΈΠ½ΠΈΠΌΠ°Π»ΡΠ½ΡΡ AND
-ΡΡΠΎΠΈΠΌΠΎΡΡΡ ΠΏΡΡΠΈ ΠΌΠ΅ΠΆΠ΄Ρ s
ΠΈ t
.
- ΠΡΠ»ΠΈ ΠΏΡΡΠΈ Π½Π΅ ΡΡΡΠ΅ΡΡΠ²ΡΠ΅Ρ, ΠΎΡΠ²Π΅Ρ
-1
.
ΠΡΠΈΠΌΠ΅Ρ
- ΠΡ
ΠΎΠ΄Π½ΡΠ΅ Π΄Π°Π½Π½ΡΠ΅:
n = 5; edges = [[0,1,7],[1,3,7],[1,2,1]]; query = [[0,3],[3,4]]
- Π Π΅Π·ΡΠ»ΡΡΠ°ΡΡ:
[1, -1]
- ΠΠ±ΡΡΡΠ½Π΅Π½ΠΈΠ΅:
- ΠΠ°ΠΈΠ»ΡΡΡΠΈΠΉ ΠΏΡΡΡ ΠΎΡ
0
Π΄ΠΎ 3
: 0 β 1 β 2 β 1 β 3
.
- ΠΡΡΠ΅ΠΉ ΠΈΠ·
3
Π² 4
Π½Π΅ ΡΡΡΠ΅ΡΡΠ²ΡΠ΅Ρ.
- ΠΡΠ°ΡΠΈΡΠ΅ΡΠΊΠ°Ρ ΠΈΠ½ΡΠ΅ΡΠΏΡΠ΅ΡΠ°ΡΠΈΡ:

π‘ ΠΠ΄Π΅Ρ
- Π’Π°ΠΊ ΠΊΠ°ΠΊ ΠΊΠ°ΠΆΠ΄ΠΎΠ΅ Π½ΠΎΠ²ΠΎΠ΅ ΡΠ΅Π±ΡΠΎ ΠΏΡΡΠΈ Π΅Π³ΠΎ ΡΡΠΎΠΈΠΌΠΎΡΡΡ Π½Π΅ ΡΠ²Π΅Π»ΠΈΡΠΈΠ²Π°Π΅Ρ, ΡΠΎ Π²Π½ΡΡΡΠΈ ΠΊΠ°ΠΆΠ΄ΠΎΠΉ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΡ ΡΠ²ΡΠ·Π½ΠΎΡΡΠΈ ΡΡΠΎΠΈΠΌΠΎΡΡΡ ΠΌΠΈΠ½ΠΈΠΌΠ°Π»ΡΠ½ΠΎΠ³ΠΎ ΠΏΡΡΠΈ Π±ΡΠ΄Π΅Ρ ΠΎΠ΄ΠΈΠ½Π°ΠΊΠΎΠ²ΠΎΠΉ (Π΄ΠΎΡΡΠ°ΡΠΎΡΠ½ΠΎ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΠΈΡΡ ΠΏΡΡΡ, ΠΏΡΠΎΡ
ΠΎΠ΄ΡΡΠΈΠΉ ΡΠ΅ΡΠ΅Π· Π²ΡΠ΅ ΡΡΠ±ΡΠ° ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΡ ΡΠ²ΡΠ·Π½ΠΎΡΡΠΈ).
- Π’Π°ΠΊΠΈΠΌ ΠΎΠ±ΡΠ°Π·ΠΎΠΌ, Π²ΠΌΠ΅ΡΡΠΎ ΠΏΠΎΠΈΡΠΊΠ° ΠΊΠΎΠ½ΠΊΡΠ΅ΡΠ½ΠΎΠ³ΠΎ ΠΏΡΡΠΈ ΠΌΠ΅ΠΆΠ΄Ρ
s
ΠΈ t
, ΠΌΠΎΠΆΠ½ΠΎ ΡΠ°Π·Π΄Π΅Π»ΠΈΡΡ Π³ΡΠ°Ρ Π½Π° ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΡ ΠΈ Π·Π°ΠΏΠΎΠΌΠ½ΠΈΡΡ ΠΌΠΈΠ½ΠΈΠΌΠ°Π»ΡΠ½ΡΠΉ AND
ΡΡΠ΅Π΄ΠΈ Π²ΡΠ΅Ρ
ΡΡΠ±Π΅Ρ Π² ΠΊΠ°ΠΆΠ΄ΠΎΠΉ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΠ΅.
- ΠΠΎΡΠ»Π΅ ΡΡΠΎΠ³ΠΎ Π»ΡΠ±ΠΎΠΉ Π·Π°ΠΏΡΠΎΡ
[s, t]
ΠΌΠΎΠΆΠ½ΠΎ ΠΎΠ±ΡΠ°Π±ΠΎΡΠ°ΡΡ Π·Π° O(1)
, ΠΏΡΠΎΡΡΠΎ ΠΏΡΠΎΠ²Π΅ΡΠΈΠ², Π½Π°Ρ
ΠΎΠ΄ΡΡΡΡ Π»ΠΈ s
ΠΈ t
Π² ΠΎΠ΄Π½ΠΎΠΉ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΠ΅.
π ΠΠ΅ΡΠ°Π»ΠΈ ΠΏΠΎΠ΄Ρ
ΠΎΠ΄Π°
- ΠΠΎΡΡΡΠΎΠ΅Π½ΠΈΠ΅ Π³ΡΠ°ΡΠ° Π² Π²ΠΈΠ΄Π΅ ΡΠΏΠΈΡΠΊΠ° ΡΠΌΠ΅ΠΆΠ½ΠΎΡΡΠΈ
graph
.
- ΠΠΎΠΈΡΠΊ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ ΡΠ²ΡΠ·Π½ΠΎΡΡΠΈ Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ ΠΎΠ±Ρ
ΠΎΠ΄Π° Π² Π³Π»ΡΠ±ΠΈΠ½Ρ (DFS):
- ΠΠ°ΠΆΠ΄ΠΎΠΉ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΠ΅ ΠΏΡΠΈΡΠ²Π°ΠΈΠ²Π°Π΅ΡΡΡ ΡΠ½ΠΈΠΊΠ°Π»ΡΠ½ΡΠΉ ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡ.
- ΠΠ΄Π½ΠΎΠ²ΡΠ΅ΠΌΠ΅Π½Π½ΠΎ Π²ΡΡΠΈΡΠ»ΡΠ΅ΡΡΡ ΠΌΠΈΠ½ΠΈΠΌΠ°Π»ΡΠ½ΡΠΉ
AND
ΡΡΠ΅Π΄ΠΈ Π²ΡΠ΅Ρ
ΡΡΠ±Π΅Ρ Π² ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΠ΅.
- ΠΠ±ΡΠ°Π±ΠΎΡΠΊΠ° Π·Π°ΠΏΡΠΎΡΠΎΠ²:
- ΠΡΠ»ΠΈ
s
ΠΈ t
ΠΏΡΠΈΠ½Π°Π΄Π»Π΅ΠΆΠ°Ρ ΡΠ°Π·Π½ΡΠΌ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΠ°ΠΌ, ΠΎΡΠ²Π΅Ρ -1
.
- ΠΡΠ»ΠΈ
s
ΠΈ t
ΠΏΡΠΈΠ½Π°Π΄Π»Π΅ΠΆΠ°Ρ ΠΎΠ΄Π½ΠΎΠΉ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΠ΅, ΠΎΡΠ²Π΅Ρ β ΠΌΠΈΠ½ΠΈΠΌΠ°Π»ΡΠ½ΡΠΉ AND
ΡΡΠΎΠΉ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΡ.
β³ ΠΡΠΈΠΌΠΏΡΠΎΡΠΈΠΊΠ°
- ΠΡΠ΅ΠΌΠ΅Π½Π½Π°Ρ ΡΠ»ΠΎΠΆΠ½ΠΎΡΡΡ:
O(N + M + Q)
- ΠΠΎΡΡΡΠΎΠ΅Π½ΠΈΠ΅ Π³ΡΠ°ΡΠ° (Π·Π°ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΡΠΏΠΈΡΠΊΠ° ΡΠΌΠ΅ΠΆΠ½ΠΎΡΡΠΈ) β
O(M)
- ΠΠΎΠΈΡΠΊ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ ΡΠ²ΡΠ·Π½ΠΎΡΡΠΈ (DFS) β
O(N + M)
- ΠΠ±ΡΠ°Π±ΠΎΡΠΊΠ° Π·Π°ΠΏΡΠΎΡΠΎΠ² β
O(Q)
- ΠΡΠΎΡΡΡΠ°Π½ΡΡΠ²Π΅Π½Π½Π°Ρ ΡΠ»ΠΎΠΆΠ½ΠΎΡΡΡ:
O(N + M)
- ΠΠ»Ρ Ρ
ΡΠ°Π½Π΅Π½ΠΈΡ Π³ΡΠ°ΡΠ° ΠΈ ΠΌΠ°ΡΡΠΈΠ²ΠΎΠ² ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ
π ΠΡΡ
ΠΎΠ΄Π½ΡΠΉ ΠΊΠΎΠ΄
impl Solution {
pub fn minimum_cost(n: i32, edges: Vec<Vec<i32>>, queries: Vec<Vec<i32>>) -> Vec<i32> {
let n = n as usize;
let mut graph = vec![Vec::new(); n];
let mut component_id = vec![-1; n];
// Build adjacency list
for edge in edges {
let (u, v, w) = (edge[0] as usize, edge[1] as usize, edge[2]);
graph[u].push((v, w));
graph[v].push((u, w));
}
let mut component_min_and = Vec::new();
// Identify components and compute min AND for each
for i in 0..n {
if component_id[i] == -1 {
component_min_and.push(Self::dfs(i, &graph, component_min_and.len() as i32, &mut component_id));
}
}
// Process queries
queries.into_iter()
.map(|q| {
let (s, t) = (component_id[q[0] as usize], component_id[q[1] as usize]);
if s != t { -1 } else { component_min_and[s as usize] }
}).collect()
}
/// Performs DFS to assign a component ID and compute the minimum bitwise AND in the component.
fn dfs(start: usize, graph: &[Vec<(usize, i32)>], id: i32, component_id: &mut [i32]) -> i32 {
let mut min_and = -1; // Tracks the minimum AND value in the component
let mut stack = vec![start];
while let Some(node) = stack.pop() {
component_id[node] = id; // Mark node as part of this component
for &(neighbor, weight) in &graph[node] {
if component_id[neighbor] == -1 {
stack.push(neighbor); // Visit unvisited neighbors
}
min_and &= weight; // Update minimum AND value
}
}
min_and
}
}
Tags: #rust #algorithms #dfs #graph
ΠΠΎΠ»Π΅Π·Π½ΠΎ Π·Π°ΠΌΠ΅ΡΠΈΡΡ, ΡΡΠΎ Π΅ΡΠ»ΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Π΄Π»Ρ ΡΠ°Π·Π±ΠΈΠ΅Π½ΠΈΡ Π½Π° ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΡ ΡΠ²ΡΠ·Π½ΠΎΡΡΠΈ ΠΏΠΎΠ΄Ρ
ΠΎΠ΄ Ρ Disjoint Set Unions
, β ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΠ»ΡΡΠΈΡΡ ΡΠ΅ΡΠ΅Π½ΠΈΠ΅, ΡΠ°Π±ΠΎΡΠ°ΡΡΠ΅Π΅ Π½Π° ΠΏΡΠ°ΠΊΡΠΈΠΊΠ΅ Π² 2 ΡΠ°Π·Π° Π±ΡΡΡΡΠ΅Π΅ Π·Π° ΡΡΡΡ Π±ΠΎΠ»Π΅Π΅ ΡΡΡΠ΅ΠΊΡΠΈΠ²Π½ΡΡ
Π°Π»Π»ΠΎΠΊΠ°ΡΠΈΠΉ ΠΏΠ°ΠΌΡΡΠΈ (Π½Π΅Ρ Π½Π΅ΠΎΠ±Ρ
ΠΎΠ΄ΠΈΠΌΠΎΡΡΠΈ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°ΡΡ ΡΠΏΠΈΡΠΊΠΈ ΡΠΌΠ΅ΠΆΠ½ΠΎΡΡΠΈ).
struct UnionFind {
parent: Vec<usize>,
size: Vec<usize>,
min_and: Vec<i32>,
}
impl Solution {
pub fn minimum_cost(n: i32, edges: Vec<Vec<i32>>, query: Vec<Vec<i32>>) -> Vec<i32> {
let n = n as usize;
let mut uf = UnionFind::new(n);
// Process edges to construct the Union-Find structure
for edge in &edges {
let (u, v, w) = (edge[0] as usize, edge[1] as usize, edge[2]);
uf.union(u, v, w);
}
// Process queries efficiently
query.into_iter().map(|q| {
let (s, t) = (uf.find(q[0] as usize), uf.find(q[1] as usize));
if s == t { uf.min_and[s] } else { -1 }
}).collect()
}
}
impl UnionFind {
fn new(n: usize) -> Self {
UnionFind {
parent: (0..n).collect(),
size: vec![1; n],
min_and: vec![-1; n],
}
}
fn find(&mut self, x: usize) -> usize {
if self.parent[x] != x {
self.parent[x] = self.find(self.parent[x]); // Path compression
}
self.parent[x]
}
fn union(&mut self, a: usize, b: usize, weight: i32) {
let mut root_a = self.find(a);
let mut root_b = self.find(b);
if root_a != root_b {
// Union by size: attach the smaller tree under the larger tree
if self.size[root_a] < self.size[root_b] {
std::mem::swap(&mut root_a, &mut root_b);
}
self.parent[root_b] = root_a;
self.size[root_a] += self.size[root_b];
self.min_and[root_a] &= self.min_and[root_b];
}
// Update min_and for the new root
self.min_and[root_a] &= weight;
}
}
ΠΎΡΠ²Π΅ΡΠΈΡΡ