int minimumEffortPath(int* heights, int heightsSize, int* heightsColSize) { int m = heightsSize; int n = heightsColSize[0]; struct Tuple edges[n * m * 2]; int edgesSize = 0; for (int i = 0; i < m; ++i) { for (int j = 0; j < n; ++j) { int id = i * n + j; if (i > 0) { edges[edgesSize].x = id - n; edges[edgesSize].y = id; edges[edgesSize++].z = fabs(heights[i][j] - heights[i - 1][j]); } if (j > 0) { edges[edgesSize].x = id - 1; edges[edgesSize].y = id; edges[edgesSize++].z = fabs(heights[i][j] - heights[i][j - 1]); } } } qsort(edges, edgesSize, sizeof(struct Tuple), cmp); struct DisjointSetUnion* uf = malloc(sizeof(struct DisjointSetUnion)); initDSU(uf, m * n); int ans = 0; for (int i = 0; i < edgesSize; i++) { unionSet(uf, edges[i].x, edges[i].y); if (connected(uf, 0, m * n - 1)) { ans = edges[i].z; break; } } return ans; }为这段代码写注释
时间: 2023-06-16 21:06:43 浏览: 87
```c
/**
* @brief 利用并查集和最小生成树的思想,求解从左上角到右下角最小代价路径
*
* @param heights 每个点的高度,heights[i][j]表示第i行第j列的高度
* @param heightsSize heights数组的行数
* @param heightsColSize heights数组的列数,即每行的元素个数
* @return int 返回最小代价路径的代价
*/
int minimumEffortPath(int* heights, int heightsSize, int* heightsColSize) {
int m = heightsSize; // 行数
int n = heightsColSize[0]; // 列数
struct Tuple edges[n * m * 2]; // 存储所有边的数组
int edgesSize = 0; // 边的数量
for (int i = 0; i < m; ++i) { // 枚举所有节点
for (int j = 0; j < n; ++j) {
int id = i * n + j; // 计算节点在一维数组中的下标
if (i > 0) { // 如果当前节点不在第一行,则与上面的节点相连
edges[edgesSize].x = id - n; // 边的起点
edges[edgesSize].y = id; // 边的终点
edges[edgesSize++].z = fabs(heights[i][j] - heights[i - 1][j]); // 边的权值,即两个节点高度差的绝对值
}
if (j > 0) { // 如果当前节点不在第一列,则与左边的节点相连
edges[edgesSize].x = id - 1; // 边的起点
edges[edgesSize].y = id; // 边的终点
edges[edgesSize++].z = fabs(heights[i][j] - heights[i][j - 1]); // 边的权值,即两个节点高度差的绝对值
}
}
}
qsort(edges, edgesSize, sizeof(struct Tuple), cmp); // 将边按照权值从小到大排序
struct DisjointSetUnion* uf = malloc(sizeof(struct DisjointSetUnion)); // 初始化并查集
initDSU(uf, m * n);
int ans = 0; // 最小代价路径的代价
for (int i = 0; i < edgesSize; i++) { // 枚举所有边
unionSet(uf, edges[i].x, edges[i].y); // 将两个节点所在的集合合并
if (connected(uf, 0, m * n - 1)) { // 如果左上角和右下角在同一个集合中,则代表已经找到最小代价路径
ans = edges[i].z; // 更新最小代价路径的代价
break;
}
}
return ans; // 返回最小代价路径的代价
}
```
阅读全文