2421 Constructing Roads 解题报告

本文通过一道具体的题目详细介绍了如何使用Kruskal算法解决最小生成树问题,并分享了作者在实现过程中遇到的各种坑及解决经验。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

AccecptTime:              2008-12-20 15:13:59
Language:                     C++
Memory:                      360K
Time:                            47MS
Errors:                          (10+)RE  + (5+)TL + (10+)WA
Algorithm:                    Kruskal

 

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <iostream>
  4. using namespace std;
  5. typedef struct Edge
  6. {
  7.     int x;
  8.     int y;
  9.     int lenght;
  10. }Edge;
  11. Edge edge[5000];
  12. int parent[101];
  13. int compare(const void* a,const void* b)
  14. {
  15.     return ((Edge*)a)->lenght - ((Edge*)b)->lenght;
  16. }
  17. //寻父节点加压缩路径
  18. int FindParent(int x)
  19. {
  20.     if(parent[x] > 0 ){
  21.         parent[x] = FindParent(parent[x]);
  22.         return parent[x];
  23.     }
  24.     return x;
  25. }
  26. //合并集合 用祖先节点的parent(<0)的绝对值来表示后代的个数
  27. //将后代少的加入后代多的 这样能减少寻找父节点的运算量
  28. void MergeSet(int x,int y)
  29. {
  30.     x = FindParent(x);
  31.     y = FindParent(y);
  32.     // notice:在加入x,y时有可能x,y已经在同一集合里边了
  33.     // 我就栽在这的
  34.     if( x == y)
  35.         return ;
  36.     if( parent[x] < parent[y])  {
  37.         parent[x] += parent[y];
  38.         parent[y] = x;
  39.     }
  40.     else {
  41.             parent[y] += parent[x];
  42.             parent[x] = y;
  43.         }       
  44. }
  45. int main()
  46. {
  47.     int n,count ,lenght;
  48.     unsigned long long sum;
  49.     int x,y,m;
  50.     int null;
  51.     char s[100];
  52.     scanf("%d",&n);
  53.     count = 0;
  54.     forint i = 1; i <= n; i++) {
  55.         for(int j = 1; j < i;j++) {
  56.             scanf("%d",&lenght);
  57.             edge[count].x = i;
  58.             edge[count].y = j;
  59.             edge[count].lenght = lenght;
  60.             count++;
  61.         }
  62.         //因为用的是Kruskal,只需读取上三角的数据
  63.         //现将多余的数据用null吞掉
  64.         for(int j = i; j <= n;j++)
  65.             scanf("%d",&null);
  66.     }
  67.     forint i = 1; i <= n; i++)
  68.         parent[i] = 0;
  69.     qsort(edge,count,sizeof(Edge),compare);
  70.     //在这读入已经存在的路
  71.     scanf("%d",&m);
  72.     forint i = 0; i < m; i++) {
  73.         scanf("%d%d",&x,&y);
  74.         MergeSet(x,y);
  75.     }
  76.     sum = 0;
  77.     //notice:不可以用 cout > 0 作为循环条件
  78.     //因为有可能在  加入存在的路时有多余的路径
  79.     //例如a,b已经间接连通,但后边又给了一个a,b直接连通的路
  80.     forint i = 0;i < count; i++) 
  81.         if(FindParent(edge[i].x) != FindParent(edge[i].y)) {
  82.             MergeSet(edge[i].x,edge[i].y);
  83.             sum += edge[i].lenght;
  84.         }
  85.         printf("%d/n",sum);
  86. }

为了这道题我贡献了10+wa,5+re,5+tl ,几乎能错的都错了.虽然它很水,之前也做过一些类似的题,但是还是被它阴了...这里读入以存在路径的时候可能会有重复的路径。这是我一直忽略的。做这道题用了很多的时间,但也得到了很多的经验,譬如用祖先的parent作为它的秩来对合并进行优化。另外我的代码风格还不是很好,恩,努力~~

### 构造对象的概念 在编程中,构造对象通常涉及创建类的一个实例并初始化其属性。这一过程通过调用类中的特殊方法——即构造函数来完成。构造函数的主要作用是在对象被创建时执行必要的初始化操作。 #### 面向对象编程中的构造器 在一个典型的面向对象语言(如Java或SystemVerilog)中,可以通过定义一个具有特定名称的构造函数来实现对象的构建[^1]。例如,在引用的内容中提到 `class ClassA` 的定义中隐含了一个构造逻辑的存在。虽然未显式展示,但在实际应用中,构造函数可能类似于以下形式: ```verilog class ClassA; int value; function new(int init_value); this.value = init_value; // 初始化成员变量 endfunction : new endclass ``` 上述代码展示了如何通过 `new` 函数作为构造函数来初始化 `value` 属性。当一个新的 `ClassA` 对象被创建时,会自动调用此构造函数,并传入初始值以设置该对象的状态。 #### 数据结构与算法视角下的对象构造 从数据结构的角度来看,构造对象不仅限于简单的赋值行为,还涉及到复杂的数据管理策略。例如,数组和链表这样的基础数据结构可以用来表示更高级别的抽象数据类型,比如栈、队列或者二叉树等[^2]。这些复杂的结构往往也需要在其内部维护状态信息,因此它们的构造过程可能会更加复杂。 考虑下面这个例子,它演示了如何使用Python来构造一个基于列表实现的堆栈对象: ```python class Stack: def __init__(self): # 这是一个构造函数 self.items = [] # 初始化为空列表 def push(self, item): self.items.append(item) def pop(self): return self.items.pop() stack_instance = Stack() # 创建Stack的对象 stack_instance.push(10) print(stack_instance.pop()) # 输出最后压入的元素 ``` 在这个案例里,`__init__()` 方法扮演着构造函数的角色,负责建立新的 `Stack` 实例及其关联的存储空间。 #### 动态链接库(DLLs)上下文中对象的构造注意事项 如果讨论的是动态链接库环境下的对象构造,则需要注意额外的因素,例如依赖关系管理和权限问题。假如遇到错误消息 `"Cannot open DllXYZ.dll for writing"` ,这表明可能存在文件访问冲突或者是缺少某些运行所需的外部DLL支持等问题[^4]。解决这类情况需要确保所有必需的组件都已正确定位并且可由应用程序加载。 ### 总结 综上所述,无论在哪种具体的编程场景下,“如何构造一个对象”的答案都会围绕几个核心要素展开:一是明确目标类型的特性;二是合理设计用于启动新实体生命周期的操作序列;三是妥善处理任何可能出现的技术障碍。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值