Created
February 28, 2024 08:11
-
-
Save crazyoptimist/05515f7f949f28a809dd03d9869c8aa3 to your computer and use it in GitHub Desktop.
There is a network with N roads and N + 1 cities. The cities are labeled with distinct integers within the range [O..N]. Roads connect the cities in such a way that there is exactly one way to travel between any two of the cities. In other words, the network forms a tree.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"strconv" | |
) | |
func solution(A []int, B []int) int { | |
n := len(A) | |
graph := make([][]int, n+1) | |
// track visited nodes when traversing the graph | |
visited := make([]bool, n+1) | |
// changes needed | |
count := 0 | |
// track directions in hashmap | |
directions := make(map[string]int) | |
// build graph | |
for i := 0; i < n; i++ { | |
graph[A[i]] = append(graph[A[i]], B[i]) | |
graph[B[i]] = append(graph[B[i]], A[i]) | |
directionKey := strconv.Itoa(A[i]) + "->" + strconv.Itoa(B[i]) | |
directions[directionKey] = 0 | |
} | |
// use closure, which is convinient in this case | |
var dfs func(city int) | |
// depth first search | |
dfs = func(city int) { | |
// mark the current city as visited | |
visited[city] = true | |
// traverse all neighbors | |
for _, neighbor := range graph[city] { | |
// skip already visited neighbor | |
if visited[neighbor] { | |
continue | |
} | |
// check if current neighbor needs change | |
changedDirectionKey := strconv.Itoa(neighbor) + "->" + strconv.Itoa(city) | |
if _, exists := directions[changedDirectionKey]; !exists { | |
count++ | |
} | |
// dfs from the current neighbor | |
dfs(neighbor) | |
} | |
} | |
// dfs from 0 | |
dfs(0) | |
return count | |
} | |
func main() { | |
A := []int{0, 2, 2, 3} | |
B := []int{1, 1, 4, 4} | |
// A := []int{1, 6, 6, 3, 0, 5} | |
// B := []int{6, 2, 0, 0, 4, 0} | |
result := solution(A, B) | |
println("result: ", result) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
There is a network with N roads and N + 1 cities. The cities are labeled with distinct integers within the range [O..N]. Roads connect the cities in such a way that there is exactly one way to travel between any two of the cities. In other words, the network forms a tree. The roads in the network are too narrow to accommodate two cars. For this reason, every road (that connects cities A and B) is oriented in one of two possible ways: either from A to B, or from B to A. If the road is oriented from A to B, then every car traveling from B to A has to give way to cars traveling from A to B. This, naturally, makes traveling from A to B much faster than traveling from B to A. A big hospital was recently founded in the city labeled 0. For that reason, the citizens have decided to rearrange the orientation of the roads so that everyone can get to the hospital as quickly as possible. This means that the trip from every city to the oth city should not go through any road that faces against the current direction of travel. In order to minimize the cost of this operation, they would like to reorient as few roads as possible. Write a function: int solution (vector int> &A, vector &B); that, given the description of the network as two arrays A, B of N integers each, returns the minimum number of roads that must be reoriented in order to make everyone's trip to the hospital as fast as possible. Arrays A and B describe the network in the following way: for each K the range [0..N-1], there is a road between cities labeled A[K] and B[K] that is oriented from A[K] to B[K].
Examples:
This is a Codility challenge, is also similiar to Leetcode #1466 - "Reorder Routes To Make All Paths Lead To The City Zero"
Hope this could help someone!