C:Runtime Error.
题目:https://www.luogu.com.cn/problem/P8655代码:
#include <stdio.h>
int main()
{
int N;
scanf("%d",&N);
int link;
int ans;
int a,b;
int index;
for(int i = 0;i < N+1;i++)
{
for(int j = 0;j < N+1;j++)
{
link = 0;
}
ans = 0;
}
for (int i = 0;i < N;i++)
{
scanf("%d %d",&a,&b);
ans++;
ans++;
link = 1;
link = 1;
}
for (int i = 1;i < N+1;i++)
{
if (ans == 1)
{
index = i;
cut:
ans--;
for (int j = 0;j < N;j++)
{
if (link == 1)
{
ans--;
link = 0;
link = 0;
if (ans == 1)
{
index = j;
goto cut;
}
}
}
}
}
for(int i = 1;i < N+1;i++)
{
if (ans != 0)
{
printf("%d ",i);
}
}
//printf("\b\n");
return 0;
}
问题:
Runtime Error. Received signal 11: Segmentation fault with invalid memory reference.
您的代码存在几个主要问题导致运行时错误(段错误):
1. 没有使用数组存储图结构,导致无法处理输入数据
2. 变量使用混乱(如 link 和 ans 被反复覆盖)
3. 使用 goto 导致逻辑混乱
4. 未初始化关键数据结构
以下是修正后的代码(使用拓扑排序):
#include <stdio.h>
#include <string.h>
#define MAXN 100010
int head, ver, next, tot;
int deg, queue, vis;
void add(int u, int v) {
ver[++tot] = v;
next = head;
head = tot;
deg++;
}
int main() {
int N;
scanf("%d", &N);
memset(head, 0, sizeof(head));
memset(deg, 0, sizeof(deg));
tot = 0;
// 读入边并建图
for (int i = 0; i < N; i++) {
int a, b;
scanf("%d %d", &a, &b);
add(a, b);
add(b, a);
}
// 将度为1的节点入队
int front = 0, rear = 0;
for (int i = 1; i <= N; i++) {
if (deg == 1) {
queue = i;
}
}
// 拓扑排序
while (front < rear) {
int u = queue;
vis = 1;// 标记为非环节点
for (int i = head; i; i = next) {
int v = ver;
if (--deg == 1) {
queue = v;
}
}
}
// 输出环上的节点(度>=2的节点)
for (int i = 1; i <= N; i++) {
if (!vis) {
printf("%d ", i);
}
}
return 0;
}
关键修改:
1. 使用邻接表存储图结构(head/ver/next 数组)
2. 添加度数组 deg 记录每个节点的度数
3. 拓扑排序过程:
- 将所有度为1的节点入队(树节点)
- 依次移除度为1的节点并更新邻居度数
- 剩余度≥2的节点即为环上节点
4. 使用 vis 数组标记已处理节点
时间复杂度:O(N),适用于题目最大数据范围(10^5个点)
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。 FishC 发表于 2025-7-19 19:51
您的代码存在几个主要问题导致运行时错误(段错误):
1. 没有使用数组存储图结构,导致无法处理输入数 ...
我初始化了
for(int i = 0;i < N+1;i++)
{
for(int j = 0;j < N+1;j++)
{
link = 0;
}
ans = 0;
}
错误是这个:
Runtime Error. Received signal 11: Segmentation fault with invalid memory reference. 风眠 发表于 2025-07-19 19:54
FishC 发表于 2025-7-19 19:51
您的代码存在几个主要 ...
您的代码出现段错误(Segmentation fault)的主要原因是没有正确初始化和使用数据结构。以下是关键问题分析和修正方案:
### 问题分析
1. **变量未正确初始化**:
- 您使用双重循环试图初始化变量,但 `link` 和 `ans` 只是普通 `int` 变量,不是数组
- 循环中的赋值 `link = 0;` 和 `ans = 0;` 会被后续覆盖,实际无效
2. **缺少图数据结构**:
- 题目需要处理树加一条边的图结构
- 必须使用邻接表或邻接矩阵存储节点连接关系
3. **无效的环检测逻辑**:
- 使用 `goto` 和手动维护 `link`/`ans` 无法正确检测环
- 拓扑排序是更可靠的解决方案
### 修正代码
#include <stdio.h>
#include <string.h>
#define MAXN 100010
int head, ver, nxt;
int deg, q, vis;
int tot = 0;
void add(int u, int v) {
ver[++tot] = v;
nxt = head;
head = tot;
deg++;
}
int main() {
int N;
scanf("%d", &N);
memset(head, 0, sizeof(head));
memset(deg, 0, sizeof(deg));
tot = 0;
for (int i = 0; i < N; i++) {
int a, b;
scanf("%d %d", &a, &b);
add(a, b);
add(b, a);
}
int front = 0, rear = 0;
for (int i = 1; i <= N; i++) {
if (deg == 1) {
q = i;
}
}
while (front < rear) {
int u = q;
vis = 1;
for (int i = head; i; i = nxt) {
int v = ver;
if (--deg == 1) {
q = v;
}
}
}
for (int i = 1; i <= N; i++) {
if (!vis) {
printf("%d ", i);
}
}
return 0;
}
### 关键改进
1. **使用邻接表存储图**:
- head 存储每个节点的第一条边
- ver[] 存储边指向的节点
- nxt[] 存储下一条边
2. **拓扑排序检测环**:
- 初始化所有度为1的节点入队
- 逐步删除度为1的节点(相当于剪枝)
- 最终未被访问的节点即在环上
3. **正确的初始化**:
- 使用 memset 初始化数组
- 显式设置 tot = 0
> 此解法时间复杂度 O(N),通过拓扑排序高效检测环。注意节点编号从1开始,输出时按升序排列环上节点。
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。 你应该把题目复制过来给 AI 看(复制 MarkDown)。 可以多发~~ 不二如是 发表于 2025-7-20 11:49
可以多发~~
?
页:
[1]