一个简单的边界错误,竟让我卡题十七天 😭😭😭🤕🤕🤕

错误代码

#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,因为你使用的是从 1n 的节点编号。如果只使用 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;
}

修正后的逻辑

  1. ans 初始化为 0:确保在没有可达节点时,ans 的值不会被错误地设置为当前节点编号。
  2. 循环范围修正为 1n:正确遍历所有节点。
  3. Visited 数组大小修正:确保数组大小足够,并正确初始化。
  4. 处理孤立节点:如果从某个节点出发无法到达其他节点,则输出该节点编号。

希望这些改进能帮助你解决问题!如果还有其他疑问,欢迎继续提问。

by Kimi.ai

0 comments

No comments so far...

Information

ID
969
Time
1000ms
Memory
256MiB
Difficulty
5
Tags
(None)
# Submissions
72
Accepted
26
Uploaded By