diff --git a/leetcode/3101-3200/3108.Minimum-Cost-Walk-in-Weighted-Graph/1.png b/leetcode/3101-3200/3108.Minimum-Cost-Walk-in-Weighted-Graph/1.png new file mode 100644 index 000000000..b4f525e6a Binary files /dev/null and b/leetcode/3101-3200/3108.Minimum-Cost-Walk-in-Weighted-Graph/1.png differ diff --git a/leetcode/3101-3200/3108.Minimum-Cost-Walk-in-Weighted-Graph/2.png b/leetcode/3101-3200/3108.Minimum-Cost-Walk-in-Weighted-Graph/2.png new file mode 100644 index 000000000..931cd9f66 Binary files /dev/null and b/leetcode/3101-3200/3108.Minimum-Cost-Walk-in-Weighted-Graph/2.png differ diff --git a/leetcode/3101-3200/3108.Minimum-Cost-Walk-in-Weighted-Graph/README.md b/leetcode/3101-3200/3108.Minimum-Cost-Walk-in-Weighted-Graph/README.md index 1e237a1b7..af2c18cce 100755 --- a/leetcode/3101-3200/3108.Minimum-Cost-Walk-in-Weighted-Graph/README.md +++ b/leetcode/3101-3200/3108.Minimum-Cost-Walk-in-Weighted-Graph/README.md @@ -1,28 +1,48 @@ # [3108.Minimum Cost Walk in Weighted Graph][title] -> [!WARNING|style:flat] -> This question is temporarily unanswered if you have good ideas. Welcome to [Create Pull Request PR](https://github.com/kylesliu/awesome-golang-algorithm) - ## Description +There is an undirected weighted graph with `n` vertices labeled from `0` to `n - 1`. + +You are given the integer `n` and an array `edges`, where `edges[i] = [ui, vi, wi]` indicates that there is an edge between vertices `ui` and `vi` with a weight of `wi`. + +A walk on a graph is a sequence of vertices and edges. The walk starts and ends with a vertex, and each edge connects the vertex that comes before it and the vertex that comes after it. It's important to note that a walk may visit the same edge or vertex more than once. + +The **cost** of a walk starting at node `u` and ending at node `v` is defined as the bitwise `AND` of the weights of the edges traversed during the walk. In other words, if the sequence of edge weights encountered during the walk is `w0, w1, w2, ..., wk`, then the cost is calculated as `w0 & w1 & w2 & ... & wk`, where `&` denotes the bitwise `AND` operator. + +You are also given a 2D array `query`, where `query[i] = [si, ti]`. For each query, you need to find the minimum cost of the walk starting at vertex `si` and ending at vertex `ti`. If there exists no such walk, the answer is `-1`. + +Return the array `answer`, where `answer[i]` denotes the **minimum** cost of a walk for query `i`. + +**Example 1:** + +![1](./1.png) -**Example 1:** ``` -Input: a = "11", b = "1" -Output: "100" +Input: n = 5, edges = [[0,1,7],[1,3,7],[1,2,1]], query = [[0,3],[3,4]] + +Output: [1,-1] + +Explanation: + +To achieve the cost of 1 in the first query, we need to move on the following edges: 0->1 (weight 7), 1->2 (weight 1), 2->1 (weight 1), 1->3 (weight 7). + +In the second query, there is no walk between nodes 3 and 4, so the answer is -1. ``` -## 题意 -> ... +**Example 2:** + +![2](./2.png) -## 题解 -### 思路1 -> ... -Minimum Cost Walk in Weighted Graph -```go ``` +Input: n = 3, edges = [[0,2,7],[0,1,15],[1,2,6],[1,2,1]], query = [[1,2]] + +Output: [0] +Explanation: +To achieve the cost of 0 in the first query, we need to move on the following edges: 1->2 (weight 1), 2->1 (weight 6), 1->2 (weight 1). +``` ## 结语 diff --git a/leetcode/3101-3200/3108.Minimum-Cost-Walk-in-Weighted-Graph/Solution.go b/leetcode/3101-3200/3108.Minimum-Cost-Walk-in-Weighted-Graph/Solution.go index d115ccf5e..e6b071695 100644 --- a/leetcode/3101-3200/3108.Minimum-Cost-Walk-in-Weighted-Graph/Solution.go +++ b/leetcode/3101-3200/3108.Minimum-Cost-Walk-in-Weighted-Graph/Solution.go @@ -1,5 +1,50 @@ package Solution -func Solution(x bool) bool { - return x +type unionFind3108 struct { + father []int + weight []int +} + +func (u *unionFind3108) find(x int) int { + if u.father[x] != x { + u.father[x] = u.find(u.father[x]) + } + return u.father[x] +} + +func (u *unionFind3108) union(x, y, w int) { + fx := u.find(x) + fy := u.find(y) + if fx < fy { + u.father[fy] = fx + u.weight[fx] = u.weight[fx] & u.weight[fy] & w + } else { + u.father[fx] = fy + u.weight[fy] = u.weight[fx] & u.weight[fy] & w + } +} + +func Solution(n int, edges [][]int, query [][]int) []int { + u := &unionFind3108{father: make([]int, n), weight: make([]int, n)} + for i := range n { + u.father[i] = i + u.weight[i] = 0xffffffff + } + + for _, e := range edges { + f, t, w := e[0], e[1], e[2] + u.union(f, t, w) + } + ans := make([]int, len(query)) + for i, q := range query { + f, t := q[0], q[1] + ff := u.find(f) + tf := u.find(t) + if ff != tf { + ans[i] = -1 + continue + } + ans[i] = u.weight[ff] + } + return ans } diff --git a/leetcode/3101-3200/3108.Minimum-Cost-Walk-in-Weighted-Graph/Solution_test.go b/leetcode/3101-3200/3108.Minimum-Cost-Walk-in-Weighted-Graph/Solution_test.go index 14ff50eb4..82f7733f1 100644 --- a/leetcode/3101-3200/3108.Minimum-Cost-Walk-in-Weighted-Graph/Solution_test.go +++ b/leetcode/3101-3200/3108.Minimum-Cost-Walk-in-Weighted-Graph/Solution_test.go @@ -10,30 +10,31 @@ func TestSolution(t *testing.T) { // 测试用例 cases := []struct { name string - inputs bool - expect bool + n int + edges [][]int + query [][]int + expect []int }{ - {"TestCase", true, true}, - {"TestCase", true, true}, - {"TestCase", false, false}, + {"TestCase1", 5, [][]int{{0, 1, 7}, {1, 3, 7}, {1, 2, 1}}, [][]int{{0, 3}, {3, 4}}, []int{1, -1}}, + {"TestCase2", 3, [][]int{{0, 2, 7}, {0, 1, 15}, {1, 2, 6}, {1, 2, 1}}, [][]int{{1, 2}}, []int{0}}, } // 开始测试 for i, c := range cases { t.Run(c.name+" "+strconv.Itoa(i), func(t *testing.T) { - got := Solution(c.inputs) + got := Solution(c.n, c.edges, c.query) if !reflect.DeepEqual(got, c.expect) { - t.Fatalf("expected: %v, but got: %v, with inputs: %v", - c.expect, got, c.inputs) + t.Fatalf("expected: %v, but got: %v, with inputs: %v %v %v", + c.expect, got, c.n, c.edges, c.query) } }) } } -// 压力测试 +// 压力测试 func BenchmarkSolution(b *testing.B) { } -// 使用案列 +// 使用案列 func ExampleSolution() { }