最近同门找我组队打2025年的“华为软件挑战杯”,他让我准备一下,刷一下“代码随想录”。我的想法是结合AI和现有的算法竞赛题,边做边学,同时做一下学习记录。我选了一个正在进行的比赛华为算法精英实战营第十九期-Minimum Cost Trees,比赛截至时间是2025年2月28日,现在的时间是16日,我们先看一下题目;
0 题目背景:
- 通信网络 (Communication Network) 表示为一个有向图 G (Directed Graph)。
- 图中的每个节点 (vertex) 代表一个通信设备或交换机。
- 图中的每条有向边 (directed edge, aka arc)表示从一个设备向另一个设备传输信号的通道。
- 源点 s (Source) 是信息的发送点。
- 多个目标点 (𝑡𝑖,terminals)是接收者。
1 题目简介:
给定一个有向图,要求找到1 或 2 棵从起点 s 到所有终点 t 的最小成本有向树,并根据完成程度评分。
1.1 有向图与有向树的基础概念:
有向图 (Directed Graph):节点之间的连接具有方向性,即从一个节点出发只能朝特定方向到达另一个节点。
例:A → B 表示从 A 到 B 有通路,但不代表 B → A 也通畅。
有向树 (Directed Tree):一种特殊的有向图,需满足以下条件:
- 连通性:任意两个节点之间有且仅有一条路径。
- 无环性:图中不存在从某节点出发再回到自身的路径。
- 唯一根节点:有向树中所有边的方向从根节点开始,扩展至所有节点。
程序示例
#include <stdio.h>
#include <limits.h>
#include <stdbool.h>
#define MAX_NODES 100
int graph[MAX_NODES][MAX_NODES];
bool visited[MAX_NODES];
int n, edges;
void dfs(int node) {
visited[node] = true;
for (int i = 0; i < n; i++) {
if (graph[node][i] && !visited[i]) {
printf("%d %d\n", node, i);
dfs(i);
}
}
}
int main() {
scanf("%d %d", &n, &edges);
for (int i = 0; i < edges; i++) {
int a, b;
scanf("%d %d", &a, &b);
graph[a][b] = 1;
}
printf("1\n"); // 输出找到 1 棵树
printf("%d\n", n - 1);
dfs(0);
return 0;
}
程序运行示例:
输入示例:
5 6
0 1
0 2
1 3
2 3
3 4
1 4
输出示例:
1
4
0 1
1 3
3 4
0 2
🚀 解释:
程序读取图并存储邻接矩阵。
使用 dfs() 递归查找从 0 出发的有向树。
输出包含树中的边,符合赛题要求。
2 任务目标:
从源点 𝑠出发,找到两棵满足条件的有向树 𝑇1和 𝑇2,用于向所有接收者
𝑡𝑖传递信号。
- 每棵树表示从源点 𝑠到所有目标点 𝑡𝑖的 一组路径集合 (paths)。
- 每棵树都是从源点出发的一棵 有向生成树 (Directed Tree),覆盖所有目标点。
参考
- 努力的青菜的文章《数据结构:二叉树概念篇(算法基础)》
- 代码随想录