输出:
yes
class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">
用例四:
输入:
5
4 3
0 4
2 1
3 2
class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">
输出:
yes
class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">
python解法
有 N 个格子,从 0 到 N-1 编号,某些格子之间存在方向性跳跃规则(例如,从格子 u 可以跳到格子 v)。
给定所有跳跃规则,判断是否可以遍历完所有的格子。
问题本质是判断图是否为一个有向无环图(DAG),并且是否可以通过拓扑排序遍历所有节点。
解决方案
使用拓扑排序检测是否可以遍历所有节点:
构建图:用邻接表表示跳跃规则。
统计每个节点的入度(被指向的次数)。
将入度为 0 的节点加入队列,表示这些节点可以作为起始点。
依次从队列中取出节点,减少其邻居节点的入度。如果邻居节点的入度减为 0,将其加入队列。
如果最终遍历的节点数等于总格子数 N,则说明可以遍历完所有格子。
算法流程
初始化邻接表 graph 和入度数组 in_degree。
遍历所有跳跃规则,构建图并更新入度。
初始化队列,将入度为 0 的节点加入队列。
使用队列进行拓扑排序,逐步减少节点的入度。
检查是否访问了所有节点:
如果访问的节点数等于 N,返回 “yes”;
否则,返回 “no”
from collections import deque, defaultdict
def can_finish_all_grids(N, steps):
"""
判断是否可以跳完所有格子
:param N: 格子数量
:param steps: 跳跃规则,格式为 [[u1, v1], [u2, v2], ...]
:return: "yes" 或 "no"
"""
graph = defaultdict(list)
in_degree = [0] * N
for step in steps:
u, v = step
graph[u].append(v)
in_degree[v] += 1
queue = deque()
for i in range(N):
if in_degree[i] == 0:
queue.append(i)
visited_count = 0
while queue:
node = queue.popleft()
visited_count += 1
for neighbor in graph[node]:
in_degree[neighbor] -= 1
if in_degree[neighbor] == 0:
queue.append(neighbor)
return "yes" if visited_count == N else "no"
import sys
input = sys.stdin.read
data = input().split()
N = int(data[0])
steps = []
for i in range(1, len(data), 2):
steps.append([int(data[i]), int(data[i + 1])])
result = can_finish_all_grids(N, steps)
print(result)
class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">
- 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
java解法
给定一个有 n 个节点的有向图,每条边表示从一个节点可以跳到另一个节点。
需要判断是否可以访问图中的所有节点,即判断图是否是一个有向无环图(DAG),并且是否所有节点都可以通过拓扑排序访问。
解决方案
使用 拓扑排序 方法判断是否可以访问所有节点:
构建图: 使用邻接表表示有向图,并记录每个节点的入度。
入度为 0 的节点入队: 初始将所有入度为 0 的节点加入队列。
广度优先遍历: 从队列中逐个取出节点,访问其邻居并减少邻居的入度。当某邻居的入度减为 0 时,将其加入队列。
统计访问的节点数: 如果访问的节点数等于图的节点总数 n,说明可以访问所有节点,否则不能。
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = Integer.parseInt(sc.nextLine());
int[] inDegree = new int[n];
List<List<Integer>> graph = new ArrayList<>();
for (int i = 0; i < n; i++) {
graph.add(new ArrayList<>());
}
while (sc.hasNextLine()) {
String line = sc.nextLine();
if (line.isEmpty()) break;
String[] parts = line.split(" ");
int from = Integer.parseInt(parts[0]);
int to = Integer.parseInt(parts[1]);
graph.get(from).add(to);
inDegree[to]++;
}
Queue<Integer> queue = new LinkedList<>();
for (int i = 0; i < n; i++) {
if (inDegree[i] == 0) {
queue.add(i);
}
}
int count = 0;
while (!queue.isEmpty()) {
int current = queue.poll();
count++;
for (int neighbor : graph.get(current)) {
inDegree[neighbor]--;
if (inDegree[neighbor] == 0) {
queue.add(neighbor);
}
}
}
System.out.println(count == n ? "yes" : "no");
}
}
class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">
- 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
C++解法
更新中
class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">
C解法
有一个包含 N 个节点的有向图,每个节点从 0 到 N-1 编号。
给定图的有向边 (u, v),表示从节点 u 可以跳到节点 v。
需要判断是否可以从图的某些起点开始访问图中的所有节点。
解决方案
使用拓扑排序(Kahn 算法)来判断图是否为有向无环图(DAG),并检查是否可以访问所有节点:
构建图和统计入度:
使用邻接表表示图,记录每个节点的出边。
使用数组记录每个节点的入度(指向它的边的数量)。
初始化队列:
将所有入度为 0 的节点加入队列,这些节点可以作为起点。
拓扑排序:
依次从队列中取出节点,访问其邻居并减少邻居节点的入度。
如果某邻居节点的入度减少到 0,将其加入队列。
判断结果:
如果最终访问的节点数等于图中的节点总数,则可以访问所有节点,返回 “yes”。
否则,返回 “no”
#include
#include
#include
typedef struct {
int* data;
int size;
int cap;
} AdjList;
typedef struct {
int* data;
int front;
int rear;
int cap;
} Queue;
Queue* create_queue(int cap) {
Queue* q = (Queue*)malloc(sizeof(Queue));
q->data = (int*)malloc(sizeof(int) * cap);
q->front = q->rear = 0;
q->cap = cap;
return q;
}
void enqueue(Queue* q, int x) {
if (q->rear == q->cap) {
q->cap *= 2;
q->data = (int*)realloc(q->data, sizeof(int) * q->cap);
}
q->data[q->rear++] = x;
}
int dequeue(Queue* q) {
if (q->front == q->rear)
return -1;
return q->data[q->front++];
}
int is_empty(Queue* q) {
return q->front == q->rear;
}
int main() {
int N;
scanf("%d", &N);
AdjList* graph = (AdjList*)malloc(sizeof(AdjList) * N);
for (int i = 0; i < N; i++) {
graph[i].data = NULL;
graph[i].size = 0;
graph[i].cap = 0;
}
int* in_degree = (int*)calloc(N, sizeof(int));
int u, v;
while (scanf("%d %d", &u, &v) != EOF) {
if (graph[u].size == graph[u].cap) {
graph[u].cap = graph[u].cap == 0 ? 2 : graph[u].cap * 2;
graph[u].data = (int*)realloc(graph[u].data, sizeof(int) * graph[u].cap);
}
graph[u].data[graph[u].size++] = v;
in_degree[v]++;
}
Queue* queue = create_queue(N);
for (int i = 0; i < N; i++) {
if (in_degree[i] == 0) {
enqueue(queue, i);
}
}
int visited_count = 0;
while (!is_empty(queue)) {
int node = dequeue(queue);
visited_count++;
for (int i = 0; i < graph[node].size; i++) {
int neighbor = graph[node].data[i];
in_degree[neighbor]--;
if (in_degree[neighbor] == 0) {
enqueue(queue, neighbor);
}
}
}
printf("%s\n", visited_count == N ? "yes" : "no");
for (int i = 0; i < N; i++) {
free(graph[i].data);
}
free(graph);
free(in_degree);
free(queue->data);
free(queue);
return 0;
}
class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">
- 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
JS解法
更新中
class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">
注意:
如果发现代码有用例覆盖不到的情况,欢迎反馈!会在第一时间修正,更新。
解题不易,如对您有帮助,欢迎点赞/收藏
评论记录:
回复评论: