- 图的遍历(简单版)
Ak!
- 2025-3-27 22:06:30 @
一个简单的边界错误,竟让我卡题十七天 😭😭😭🤕🤕🤕
错误代码
#include <iostream>
#include <vector>
using namespace std;
#define Maxn 1001
vector<int> Graph[Maxn];
bool Visited[Maxn];
int n,m,x,y,ans;
void Dfs(int u){
if(Visited[u])
return;
Visited[u] = true;
int SizeNum = Graph[u].size();
for(int i = 0;i < SizeNum;i++) {
int v = Graph[u][i];
ans = max(ans,v);
Dfs(v);
}
return;
}
int main(){
cin >> n >> m;
for(int i = 1;i <= m;i++){
cin >> x >> y;
Graph[x].push_back(y);
}
for(int i = 1;i <= m + 1;i++){
fill(Visited,Visited + n,0);
ans = i;
Dfs(i);
cout << ans << " ";
}
return 0;
}
不愧是AI
以下为AI的解释
你的代码逻辑基本正确,但存在一些问题,可能导致结果不正确或程序行为异常。以下是代码中可能存在的问题以及改进方法:
1. ans
的初始化问题
在每次调用 Dfs
函数之前,你将 ans
初始化为当前节点编号 i
。然而,如果从节点 i
出发无法到达任何其他节点,那么 ans
的值将始终是 i
,这在逻辑上是不正确的。实际上,ans
应该初始化为一个比当前节点编号小的值(例如 0
或 -1
),这样可以确保在没有可达节点时,ans
的值不会被错误地设置为当前节点编号。
改进:
ans = 0; // 初始化为0或其他小于节点编号的值
2. 循环范围错误
在主循环中,你使用了 for (int i = 1; i <= m + 1; i++)
,这显然是错误的。m
是边的数量,而你需要遍历的是所有节点(n
个节点)。正确的循环范围应该是 for (int i = 1; i <= n; i++)
。
改进:
for (int i = 1; i <= n; i++) {
fill(Visited, Visited + n + 1, 0); // 注意数组大小
ans = 0; // 初始化为0
Dfs(i);
cout << ans << " ";
}
3. Visited
数组大小问题
Visited
数组的大小应该是 n + 1
,因为你使用的是从 1
到 n
的节点编号。如果只使用 n
的大小,可能会导致数组越界。
改进:
bool Visited[Maxn]; // 确保数组大小足够
或者在调用 fill
函数时,确保范围正确:
fill(Visited + 1, Visited + n + 1, 0);
4. ans
的更新问题
在 Dfs
函数中,ans
的更新逻辑是正确的,但需要确保在递归调用 Dfs
时,ans
的值能够正确传递。由于 ans
是全局变量,这一点在你的代码中已经实现了,但需要注意其值的更新顺序。
5. 未处理孤立节点的情况
如果某个节点是孤立的(即没有出边),那么从该节点出发无法到达任何其他节点。在这种情况下,ans
的值应该保持为初始值(0
或其他默认值)。你的代码中已经通过初始化 ans
来处理这一点,但需要确保逻辑正确。
修正后的代码
以下是修正后的代码:
#include <iostream>
#include <vector>
using namespace std;
#define Maxn 1001
vector<int> Graph[Maxn];
bool Visited[Maxn];
int n, m, x, y, ans;
void Dfs(int u) {
if (Visited[u])
return;
Visited[u] = true;
int SizeNum = Graph[u].size();
for (int i = 0; i < SizeNum; i++) {
int v = Graph[u][i];
ans = max(ans, v); // 更新ans
Dfs(v);
}
return;
}
int main() {
cin >> n >> m;
for (int i = 1; i <= m; i++) {
cin >> x >> y;
Graph[x].push_back(y);
}
for (int i = 1; i <= n; i++) { // 遍历所有节点
fill(Visited + 1, Visited + n + 1, 0); // 初始化Visited数组
ans = 0; // 初始化ans为0
Dfs(i);
if (ans == 0) {
cout << i << " "; // 如果ans为0,说明从i出发无法到达其他节点,输出i
} else {
cout << ans << " "; // 输出从i出发能到达的最大节点编号
}
}
return 0;
}
修正后的逻辑
ans
初始化为0
:确保在没有可达节点时,ans
的值不会被错误地设置为当前节点编号。- 循环范围修正为
1
到n
:正确遍历所有节点。 Visited
数组大小修正:确保数组大小足够,并正确初始化。- 处理孤立节点:如果从某个节点出发无法到达其他节点,则输出该节点编号。
希望这些改进能帮助你解决问题!如果还有其他疑问,欢迎继续提问。
by Kimi.ai
0 comments
Information
- ID
- 969
- Time
- 1000ms
- Memory
- 256MiB
- Difficulty
- 5
- Tags
- (None)
- # Submissions
- 72
- Accepted
- 26
- Uploaded By