-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path2858-MinimumEdgeReversalsSoEveryNodeIsReachable.go
More file actions
150 lines (137 loc) · 5.93 KB
/
2858-MinimumEdgeReversalsSoEveryNodeIsReachable.go
File metadata and controls
150 lines (137 loc) · 5.93 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
package main
// 2858. Minimum Edge Reversals So Every Node Is Reachable
// There is a simple directed graph with n nodes labeled from 0 to n - 1.
// The graph would form a tree if its edges were bi-directional.
// You are given an integer n and a 2D integer array edges,
// where edges[i] = [ui, vi] represents a directed edge going from node ui to node vi.
// An edge reversal changes the direction of an edge,
// i.e., a directed edge going from node ui to node vi becomes a directed edge going from node vi to node ui.
// For every node i in the range [0, n - 1],
// your task is to independently calculate the minimum number of edge reversals required so it is possible to reach any other node starting from node i through a sequence of directed edges.
// Return an integer array answer,
// where answer[i] is the minimum number of edge reversals required so it is possible to reach any other node starting from node i through a sequence of directed edges.
// Example 1:
// <img src="https://assets.leetcode.com/uploads/2023/08/26/image-20230826221104-3.png" />
// Input: n = 4, edges = [[2,0],[2,1],[1,3]]
// Output: [1,1,0,2]
// Explanation: The image above shows the graph formed by the edges.
// For node 0: after reversing the edge [2,0], it is possible to reach any other node starting from node 0.
// So, answer[0] = 1.
// For node 1: after reversing the edge [2,1], it is possible to reach any other node starting from node 1.
// So, answer[1] = 1.
// For node 2: it is already possible to reach any other node starting from node 2.
// So, answer[2] = 0.
// For node 3: after reversing the edges [1,3] and [2,1], it is possible to reach any other node starting from node 3.
// So, answer[3] = 2.
// Example 2:
// <img src="https://assets.leetcode.com/uploads/2023/08/26/image-20230826225541-2.png" />
// Input: n = 3, edges = [[1,2],[2,0]]
// Output: [2,0,1]
// Explanation: The image above shows the graph formed by the edges.
// For node 0: after reversing the edges [2,0] and [1,2], it is possible to reach any other node starting from node 0.
// So, answer[0] = 2.
// For node 1: it is already possible to reach any other node starting from node 1.
// So, answer[1] = 0.
// For node 2: after reversing the edge [1, 2], it is possible to reach any other node starting from node 2.
// So, answer[2] = 1.
// Constraints:
// 2 <= n <= 10^5
// edges.length == n - 1
// edges[i].length == 2
// 0 <= ui == edges[i][0] < n
// 0 <= vi == edges[i][1] < n
// ui != vi
// The input is generated such that if the edges were bi-directional, the graph would be a tree.
import "fmt"
func minEdgeReversals(n int, edges [][]int) []int {
graph := make(map[int]map[int]int, n)
for i := 0; i < n; i++ {
graph[i] = make(map[int]int)
}
for _, v := range edges {
graph[v[0]][v[1]], graph[v[1]][v[0]] = 0, 1
}
dp := make(map[int]map[int]int)
for i := 0; i < n; i++ {
dp[i] = make(map[int]int)
}
var dfs func(i, parent int) int
dfs = func(i, parent int) int {
sum := 0
if v, ok := dp[i][parent]; ok { return v }
for k, v := range graph[i] {
if k == parent { continue }
sum += dfs(k, i) + v
}
dp[i][parent] = sum
return sum
}
res := make([]int, n)
for i := 0; i < n; i++ {
res[i] = dfs(i, -1)
}
return res
}
func minEdgeReversals1(n int, edges [][]int) []int {
type Pair struct{ to, dir int }
graph := make([][]Pair, n)
for _, v := range edges {
x, y := v[0], v[1]
graph[x] = append(graph[x], Pair{ y, 1 })
graph[y] = append(graph[y], Pair{ x, -1 }) // 从 y 到 x 需要反向
}
res := make([]int, n)
var dfs func(int, parent int)
dfs = func(i, parent int) {
for _, p := range graph[i] {
if p.to != parent {
if p.dir < 0 {
res[0]++
}
dfs(p.to, i)
}
}
}
dfs(0, -1)
var reroot func(x, parent int)
reroot = func(x, parent int) {
for _, p := range graph[x] {
if p.to != parent {
res[p.to] = res[x] + p.dir
reroot(p.to, x)
}
}
}
reroot(0,-1)
return res
}
func main() {
// Example 1:
// <img src="https://assets.leetcode.com/uploads/2023/08/26/image-20230826221104-3.png" />
// Input: n = 4, edges = [[2,0],[2,1],[1,3]]
// Output: [1,1,0,2]
// Explanation: The image above shows the graph formed by the edges.
// For node 0: after reversing the edge [2,0], it is possible to reach any other node starting from node 0.
// So, answer[0] = 1.
// For node 1: after reversing the edge [2,1], it is possible to reach any other node starting from node 1.
// So, answer[1] = 1.
// For node 2: it is already possible to reach any other node starting from node 2.
// So, answer[2] = 0.
// For node 3: after reversing the edges [1,3] and [2,1], it is possible to reach any other node starting from node 3.
// So, answer[3] = 2.
fmt.Println(minEdgeReversals(4, [][]int{{2,0},{2,1},{1,3}})) // [1,1,0,2]
// Example 2:
// <img src="https://assets.leetcode.com/uploads/2023/08/26/image-20230826225541-2.png" />
// Input: n = 3, edges = [[1,2],[2,0]]
// Output: [2,0,1]
// Explanation: The image above shows the graph formed by the edges.
// For node 0: after reversing the edges [2,0] and [1,2], it is possible to reach any other node starting from node 0.
// So, answer[0] = 2.
// For node 1: it is already possible to reach any other node starting from node 1.
// So, answer[1] = 0.
// For node 2: after reversing the edge [1, 2], it is possible to reach any other node starting from node 2.
// So, answer[2] = 1.
fmt.Println(minEdgeReversals(3, [][]int{{1,2},{2,0}})) // [2,0,1]
fmt.Println(minEdgeReversals1(4, [][]int{{2,0},{2,1},{1,3}})) // [1,1,0,2]
fmt.Println(minEdgeReversals1(3, [][]int{{1,2},{2,0}})) // [2,0,1]
}