mirror of
https://github.com/youngyangyang04/leetcode-master.git
synced 2026-02-03 02:43:26 +08:00
Merge branch 'master' of github.com:youngyangyang04/leetcode-master
This commit is contained in:
@@ -588,6 +588,40 @@ public class Main {
|
||||
```
|
||||
|
||||
### Python
|
||||
```python
|
||||
# 接收输入
|
||||
v, e = list(map(int, input().strip().split()))
|
||||
# 按照常规的邻接矩阵存储图信息,不可达的初始化为10001
|
||||
graph = [[10001] * (v+1) for _ in range(v+1)]
|
||||
for _ in range(e):
|
||||
x, y, w = list(map(int, input().strip().split()))
|
||||
graph[x][y] = w
|
||||
graph[y][x] = w
|
||||
|
||||
# 定义加入生成树的标记数组和未加入生成树的最近距离
|
||||
visited = [False] * (v + 1)
|
||||
minDist = [10001] * (v + 1)
|
||||
|
||||
# 循环 n - 1 次,建立 n - 1 条边
|
||||
# 从节点视角来看:每次选中一个节点加入树,更新剩余的节点到树的最短距离,
|
||||
# 这一步其实蕴含了确定下一条选取的边,计入总路程 ans 的计算
|
||||
for _ in range(1, v + 1):
|
||||
min_val = 10002
|
||||
cur = -1
|
||||
for j in range(1, v + 1):
|
||||
if visited[j] == False and minDist[j] < min_val:
|
||||
cur = j
|
||||
min_val = minDist[j]
|
||||
visited[cur] = True
|
||||
for j in range(1, v + 1):
|
||||
if visited[j] == False and minDist[j] > graph[cur][j]:
|
||||
minDist[j] = graph[cur][j]
|
||||
|
||||
ans = 0
|
||||
for i in range(2, v + 1):
|
||||
ans += minDist[i]
|
||||
print(ans)
|
||||
```
|
||||
|
||||
```python
|
||||
def prim(v, e, edges):
|
||||
|
||||
@@ -422,9 +422,186 @@ int main() {
|
||||
## 其他语言版本
|
||||
|
||||
### Java
|
||||
#### 邻接矩阵写法
|
||||
```java
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Scanner;
|
||||
|
||||
public class Main {
|
||||
static List<List<Integer>> result = new ArrayList<>(); // 收集符合条件的路径
|
||||
static List<Integer> path = new ArrayList<>(); // 1节点到终点的路径
|
||||
|
||||
public static void dfs(int[][] graph, int x, int n) {
|
||||
// 当前遍历的节点x 到达节点n
|
||||
if (x == n) { // 找到符合条件的一条路径
|
||||
result.add(new ArrayList<>(path));
|
||||
return;
|
||||
}
|
||||
for (int i = 1; i <= n; i++) { // 遍历节点x链接的所有节点
|
||||
if (graph[x][i] == 1) { // 找到 x链接的节点
|
||||
path.add(i); // 遍历到的节点加入到路径中来
|
||||
dfs(graph, i, n); // 进入下一层递归
|
||||
path.remove(path.size() - 1); // 回溯,撤销本节点
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
Scanner scanner = new Scanner(System.in);
|
||||
int n = scanner.nextInt();
|
||||
int m = scanner.nextInt();
|
||||
|
||||
// 节点编号从1到n,所以申请 n+1 这么大的数组
|
||||
int[][] graph = new int[n + 1][n + 1];
|
||||
|
||||
for (int i = 0; i < m; i++) {
|
||||
int s = scanner.nextInt();
|
||||
int t = scanner.nextInt();
|
||||
// 使用邻接矩阵表示无向图,1 表示 s 与 t 是相连的
|
||||
graph[s][t] = 1;
|
||||
}
|
||||
|
||||
path.add(1); // 无论什么路径已经是从1节点出发
|
||||
dfs(graph, 1, n); // 开始遍历
|
||||
|
||||
// 输出结果
|
||||
if (result.isEmpty()) System.out.println(-1);
|
||||
for (List<Integer> pa : result) {
|
||||
for (int i = 0; i < pa.size() - 1; i++) {
|
||||
System.out.print(pa.get(i) + " ");
|
||||
}
|
||||
System.out.println(pa.get(pa.size() - 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 邻接表写法
|
||||
```java
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Scanner;
|
||||
|
||||
public class Main {
|
||||
static List<List<Integer>> result = new ArrayList<>(); // 收集符合条件的路径
|
||||
static List<Integer> path = new ArrayList<>(); // 1节点到终点的路径
|
||||
|
||||
public static void dfs(List<LinkedList<Integer>> graph, int x, int n) {
|
||||
if (x == n) { // 找到符合条件的一条路径
|
||||
result.add(new ArrayList<>(path));
|
||||
return;
|
||||
}
|
||||
for (int i : graph.get(x)) { // 找到 x指向的节点
|
||||
path.add(i); // 遍历到的节点加入到路径中来
|
||||
dfs(graph, i, n); // 进入下一层递归
|
||||
path.remove(path.size() - 1); // 回溯,撤销本节点
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
Scanner scanner = new Scanner(System.in);
|
||||
int n = scanner.nextInt();
|
||||
int m = scanner.nextInt();
|
||||
|
||||
// 节点编号从1到n,所以申请 n+1 这么大的数组
|
||||
List<LinkedList<Integer>> graph = new ArrayList<>(n + 1);
|
||||
for (int i = 0; i <= n; i++) {
|
||||
graph.add(new LinkedList<>());
|
||||
}
|
||||
|
||||
while (m-- > 0) {
|
||||
int s = scanner.nextInt();
|
||||
int t = scanner.nextInt();
|
||||
// 使用邻接表表示 s -> t 是相连的
|
||||
graph.get(s).add(t);
|
||||
}
|
||||
|
||||
path.add(1); // 无论什么路径已经是从1节点出发
|
||||
dfs(graph, 1, n); // 开始遍历
|
||||
|
||||
// 输出结果
|
||||
if (result.isEmpty()) System.out.println(-1);
|
||||
for (List<Integer> pa : result) {
|
||||
for (int i = 0; i < pa.size() - 1; i++) {
|
||||
System.out.print(pa.get(i) + " ");
|
||||
}
|
||||
System.out.println(pa.get(pa.size() - 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
### Python
|
||||
#### 邻接矩阵写法
|
||||
``` python
|
||||
def dfs(graph, x, n, path, result):
|
||||
if x == n:
|
||||
result.append(path.copy())
|
||||
return
|
||||
for i in range(1, n + 1):
|
||||
if graph[x][i] == 1:
|
||||
path.append(i)
|
||||
dfs(graph, i, n, path, result)
|
||||
path.pop()
|
||||
|
||||
def main():
|
||||
n, m = map(int, input().split())
|
||||
graph = [[0] * (n + 1) for _ in range(n + 1)]
|
||||
|
||||
for _ in range(m):
|
||||
s, t = map(int, input().split())
|
||||
graph[s][t] = 1
|
||||
|
||||
result = []
|
||||
dfs(graph, 1, n, [1], result)
|
||||
|
||||
if not result:
|
||||
print(-1)
|
||||
else:
|
||||
for path in result:
|
||||
print(' '.join(map(str, path)))
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
```
|
||||
|
||||
#### 邻接表写法
|
||||
``` python
|
||||
from collections import defaultdict
|
||||
|
||||
result = [] # 收集符合条件的路径
|
||||
path = [] # 1节点到终点的路径
|
||||
|
||||
def dfs(graph, x, n):
|
||||
if x == n: # 找到符合条件的一条路径
|
||||
result.append(path.copy())
|
||||
return
|
||||
for i in graph[x]: # 找到 x指向的节点
|
||||
path.append(i) # 遍历到的节点加入到路径中来
|
||||
dfs(graph, i, n) # 进入下一层递归
|
||||
path.pop() # 回溯,撤销本节点
|
||||
|
||||
def main():
|
||||
n, m = map(int, input().split())
|
||||
|
||||
graph = defaultdict(list) # 邻接表
|
||||
for _ in range(m):
|
||||
s, t = map(int, input().split())
|
||||
graph[s].append(t)
|
||||
|
||||
path.append(1) # 无论什么路径已经是从1节点出发
|
||||
dfs(graph, 1, n) # 开始遍历
|
||||
|
||||
# 输出结果
|
||||
if not result:
|
||||
print(-1)
|
||||
for pa in result:
|
||||
print(' '.join(map(str, pa)))
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
```
|
||||
### Go
|
||||
|
||||
### Rust
|
||||
|
||||
@@ -167,7 +167,7 @@
|
||||
|
||||

|
||||
|
||||
--------------
|
||||
--------------
|
||||
|
||||
后面的过程一样的,节点3 和 节点4,入度都为0,选哪个都行。
|
||||
|
||||
@@ -344,8 +344,107 @@ int main() {
|
||||
|
||||
### Java
|
||||
|
||||
```java
|
||||
import java.util.*;
|
||||
|
||||
|
||||
public class Main {
|
||||
public static void main(String[] args) {
|
||||
Scanner scanner = new Scanner(System.in);
|
||||
int n = scanner.nextInt();
|
||||
int m = scanner.nextInt();
|
||||
|
||||
List<List<Integer>> umap = new ArrayList<>(); // 记录文件依赖关系
|
||||
int[] inDegree = new int[n]; // 记录每个文件的入度
|
||||
|
||||
for (int i = 0; i < n; i++)
|
||||
umap.add(new ArrayList<>());
|
||||
|
||||
for (int i = 0; i < m; i++) {
|
||||
int s = scanner.nextInt();
|
||||
int t = scanner.nextInt();
|
||||
umap.get(s).add(t); // 记录s指向哪些文件
|
||||
inDegree[t]++; // t的入度加一
|
||||
}
|
||||
|
||||
Queue<Integer> queue = new LinkedList<>();
|
||||
for (int i = 0; i < n; i++) {
|
||||
if (inDegree[i] == 0) {
|
||||
// 入度为0的文件,可以作为开头,先加入队列
|
||||
queue.add(i);
|
||||
}
|
||||
}
|
||||
|
||||
List<Integer> result = new ArrayList<>();
|
||||
|
||||
// 拓扑排序
|
||||
while (!queue.isEmpty()) {
|
||||
int cur = queue.poll(); // 当前选中的文件
|
||||
result.add(cur);
|
||||
for (int file : umap.get(cur)) {
|
||||
inDegree[file]--; // cur的指向的文件入度-1
|
||||
if (inDegree[file] == 0) {
|
||||
queue.add(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (result.size() == n) {
|
||||
for (int i = 0; i < result.size(); i++) {
|
||||
System.out.print(result.get(i));
|
||||
if (i < result.size() - 1) {
|
||||
System.out.print(" ");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
System.out.println(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### Python
|
||||
|
||||
```python
|
||||
from collections import deque, defaultdict
|
||||
|
||||
def topological_sort(n, edges):
|
||||
inDegree = [0] * n # inDegree 记录每个文件的入度
|
||||
umap = defaultdict(list) # 记录文件依赖关系
|
||||
|
||||
# 构建图和入度表
|
||||
for s, t in edges:
|
||||
inDegree[t] += 1
|
||||
umap[s].append(t)
|
||||
|
||||
# 初始化队列,加入所有入度为0的节点
|
||||
queue = deque([i for i in range(n) if inDegree[i] == 0])
|
||||
result = []
|
||||
|
||||
while queue:
|
||||
cur = queue.popleft() # 当前选中的文件
|
||||
result.append(cur)
|
||||
for file in umap[cur]: # 获取该文件指向的文件
|
||||
inDegree[file] -= 1 # cur的指向的文件入度-1
|
||||
if inDegree[file] == 0:
|
||||
queue.append(file)
|
||||
|
||||
if len(result) == n:
|
||||
print(" ".join(map(str, result)))
|
||||
else:
|
||||
print(-1)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
n, m = map(int, input().split())
|
||||
edges = [tuple(map(int, input().split())) for _ in range(m)]
|
||||
topological_sort(n, edges)
|
||||
```
|
||||
|
||||
|
||||
|
||||
### Go
|
||||
|
||||
### Rust
|
||||
|
||||
Reference in New Issue
Block a user