鱼C论坛

 找回密码
 立即注册
查看: 53|回复: 6

C:Runtime Error.

[复制链接]
发表于 前天 19:49 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
题目:https://www.luogu.com.cn/problem/P8655
屏幕截图_19-7-2025_194859_www.luogu.com.cn.jpeg
代码:
  1. #include <stdio.h>


  2. int main()
  3. {
  4.         int N;
  5.         scanf("%d",&N);

  6.         int link[N+1][N+1];
  7.         int ans[N+1];
  8.         int a,b;
  9.         int index;

  10.         for(int i = 0;i < N+1;i++)
  11.         {
  12.                 for(int j = 0;j < N+1;j++)
  13.                 {
  14.                         link[i][j] = 0;
  15.                 }
  16.                 ans[i] = 0;
  17.         }
  18.         for (int i = 0;i < N;i++)
  19.         {
  20.                 scanf("%d %d",&a,&b);
  21.                 ans[a]++;
  22.                 ans[b]++;
  23.                 link[a][b] = 1;
  24.                 link[b][a] = 1;
  25.         }

  26.        
  27.         for (int i = 1;i < N+1;i++)
  28.         {
  29.                 if (ans[i] == 1)
  30.                 {
  31.                         index = i;
  32.                         cut:
  33.                         ans[index]--;
  34.                         for (int j = 0;j < N;j++)
  35.                         {
  36.                                 if (link[index][j] == 1)
  37.                                 {
  38.                                         ans[j]--;
  39.                                         link[index][j] = 0;
  40.                                         link[j][index] = 0;
  41.                                         if (ans[j] == 1)
  42.                                         {
  43.                                                 index = j;
  44.                                                 goto cut;
  45.                                         }
  46.                                 }
  47.                         }

  48.                 }
  49.         }


  50.         for(int i = 1;i < N+1;i++)
  51.         {
  52.                 if (ans[i] != 0)
  53.                 {
  54.                         printf("%d ",i);
  55.                 }
  56.         }
  57.         //printf("\b\n");
  58.        

  59.        

  60.         return 0;
  61. }
复制代码

问题:
Runtime Error. Received signal 11: Segmentation fault with invalid memory reference.
Snipaste_2025-07-19_19-47-36.png
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 前天 19:51 | 显示全部楼层
您的代码存在几个主要问题导致运行时错误(段错误):

1. 没有使用数组存储图结构,导致无法处理输入数据
2. 变量使用混乱(如 linkans 被反复覆盖)
3. 使用 goto 导致逻辑混乱
4. 未初始化关键数据结构

以下是修正后的代码(使用拓扑排序):

  1. #include <stdio.h>
  2. #include <string.h>
  3. #define MAXN 100010

  4. int head[MAXN], ver[2*MAXN], next[2*MAXN], tot;
  5. int deg[MAXN], queue[MAXN], vis[MAXN];

  6. void add(int u, int v) {
  7.     ver[++tot] = v;
  8.     next[tot] = head[u];
  9.     head[u] = tot;
  10.     deg[u]++;
  11. }

  12. int main() {
  13.     int N;
  14.     scanf("%d", &N);
  15.    
  16.     memset(head, 0, sizeof(head));
  17.     memset(deg, 0, sizeof(deg));
  18.     tot = 0;
  19.    
  20.     // 读入边并建图
  21.     for (int i = 0; i < N; i++) {
  22.         int a, b;
  23.         scanf("%d %d", &a, &b);
  24.         add(a, b);
  25.         add(b, a);
  26.     }
  27.    
  28.     // 将度为1的节点入队
  29.     int front = 0, rear = 0;
  30.     for (int i = 1; i <= N; i++) {
  31.         if (deg[i] == 1) {
  32.             queue[rear++] = i;
  33.         }
  34.     }
  35.    
  36.     // 拓扑排序
  37.     while (front < rear) {
  38.         int u = queue[front++];
  39.         vis[u] = 1;  // 标记为非环节点
  40.         
  41.         for (int i = head[u]; i; i = next[i]) {
  42.             int v = ver[i];
  43.             if (--deg[v] == 1) {
  44.                 queue[rear++] = v;
  45.             }
  46.         }
  47.     }
  48.    
  49.     // 输出环上的节点(度>=2的节点)
  50.     for (int i = 1; i <= N; i++) {
  51.         if (!vis[i]) {
  52.             printf("%d ", i);
  53.         }
  54.     }
  55.     return 0;
  56. }
复制代码


关键修改:
1. 使用邻接表存储图结构(head/ver/next 数组)
2. 添加度数组 deg 记录每个节点的度数
3. 拓扑排序过程:
   - 将所有度为1的节点入队(树节点)
   - 依次移除度为1的节点并更新邻居度数
   - 剩余度≥2的节点即为环上节点
4. 使用 vis 数组标记已处理节点

时间复杂度:O(N),适用于题目最大数据范围(10^5个点)

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 前天 19:54 | 显示全部楼层
FishC 发表于 2025-7-19 19:51
您的代码存在几个主要问题导致运行时错误(段错误):

1. 没有使用数组存储图结构,导致无法处理输入数 ...

我初始化了
  1. for(int i = 0;i < N+1;i++)
  2.         {
  3.                 for(int j = 0;j < N+1;j++)
  4.                 {
  5.                         link[i][j] = 0;
  6.                 }
  7.                 ans[i] = 0;
  8.         }
复制代码

错误是这个:
Runtime Error. Received signal 11: Segmentation fault with invalid memory reference.
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 前天 19:55 | 显示全部楼层
风眠 发表于 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` 无法正确检测环
   - 拓扑排序是更可靠的解决方案

### 修正代码
  1. #include <stdio.h>
  2. #include <string.h>
  3. #define MAXN 100010

  4. int head[MAXN], ver[MAXN*2], nxt[MAXN*2];
  5. int deg[MAXN], q[MAXN], vis[MAXN];
  6. int tot = 0;

  7. void add(int u, int v) {
  8.     ver[++tot] = v;
  9.     nxt[tot] = head[u];
  10.     head[u] = tot;
  11.     deg[v]++;
  12. }

  13. int main() {
  14.     int N;
  15.     scanf("%d", &N);
  16.    
  17.     memset(head, 0, sizeof(head));
  18.     memset(deg, 0, sizeof(deg));
  19.     tot = 0;
  20.    
  21.     for (int i = 0; i < N; i++) {
  22.         int a, b;
  23.         scanf("%d %d", &a, &b);
  24.         add(a, b);
  25.         add(b, a);
  26.     }
  27.    
  28.     int front = 0, rear = 0;
  29.     for (int i = 1; i <= N; i++) {
  30.         if (deg[i] == 1) {
  31.             q[rear++] = i;
  32.         }
  33.     }
  34.    
  35.     while (front < rear) {
  36.         int u = q[front++];
  37.         vis[u] = 1;
  38.         for (int i = head[u]; i; i = nxt[i]) {
  39.             int v = ver[i];
  40.             if (--deg[v] == 1) {
  41.                 q[rear++] = v;
  42.             }
  43.         }
  44.     }
  45.    
  46.     for (int i = 1; i <= N; i++) {
  47.         if (!vis[i]) {
  48.             printf("%d ", i);
  49.         }
  50.     }
  51.     return 0;
  52. }
复制代码


### 关键改进
1. **使用邻接表存储图**:
   - head[MAXN] 存储每个节点的第一条边
   - ver[] 存储边指向的节点
   - nxt[] 存储下一条边

2. **拓扑排序检测环**:
   - 初始化所有度为1的节点入队
   - 逐步删除度为1的节点(相当于剪枝)
   - 最终未被访问的节点即在环上

3. **正确的初始化**:
   - 使用 memset 初始化数组
   - 显式设置 tot = 0

> 此解法时间复杂度 O(N),通过拓扑排序高效检测环。注意节点编号从1开始,输出时按升序排列环上节点。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 前天 20:02 | 显示全部楼层
你应该把题目复制过来给 AI 看(复制 MarkDown)。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 昨天 11:49 | 显示全部楼层
可以多发~~
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 昨天 19:49 | 显示全部楼层
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-7-21 02:22

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表