1.23 LeetCode总结(树)_一般树

2368. 受限条件下可到达节点的数目


BFS:

c 复制代码
int reachableNodes(int n, int **edges, int edgesSize, int *edgesColSize, int *restricted, int restrictedSize)
{
    // 创建并初始化受限节点标记数组
    bool *isRestricted = (bool *)malloc(n * sizeof(bool));
    for (int i = 0; i < n; i++) {
        isRestricted[i] = false;
    }
    for (int i = 0; i < restrictedSize; i++) {
        isRestricted[restricted[i]] = true;
    }
    // 如果节点0受限,直接返回0
    if (isRestricted[0]) {
        free(isRestricted);
        return 0;
    }
    // 计算每个节点的度数,无向所以不区分入度与出度
    int *degree = (int *)malloc(n * sizeof(int));
    for (int i = 0; i < n; i++) {
        degree[i] = 0;
    }
    for (int i = 0; i < edgesSize; i++) {
        int u = edges[i][0];
        int v = edges[i][1];
        degree[u]++;
        degree[v]++;
    }
    // 创建邻接表
    int **graph = (int **)malloc(n * sizeof(int*));
    int *graphSize = (int *)malloc(n * sizeof(int));
    for (int i = 0; i < n; i++) { // 因为题目中 2 <= n <= 10^5, 所以需动态申请
        graph[i] = (int *)malloc(degree[i] * sizeof(int));
        graphSize[i] = 0; // 初始化当前邻居数量
    }
    // 填充邻接表
    for (int i = 0; i < edgesSize; i++) {
        int u = edges[i][0];
        int v = edges[i][1];
        graph[u][graphSize[u]++] = v;
        graph[v][graphSize[v]++] = u;
    }
    // 创建并初始化访问标记数组
    bool *visited = (bool *)malloc(n * sizeof(bool));
    for (int i = 0; i < n; i++) visited[i] = false;
    visited[0] = true;
    int *queue = (int*)malloc(n * sizeof(int));
    int head = 0, tail = 0;
    queue[tail++] = 0; // 从节点0开始
    int count = 1; // 包括节点0
    
    // BFS遍历
    while (head < tail) {
        int u = queue[head++];
        for (int i = 0; i < graphSize[u]; i++) {
            int v = graph[u][i];
            if (!visited[v] && !isRestricted[v]) {
                visited[v] = true;
                count++;
                queue[tail++] = v;
            }
        }
    }
    // 释放内存
    free(isRestricted);
    free(degree);
    for (int i = 0; i < n; i++) {
        free(graph[i]);
    }
    free(graph);
    free(graphSize);
    free(visited);
    free(queue);
    return count;
}

DFS:

c 复制代码
void dfs(int u, int **graph, int *graphSize, bool *visited, bool *isRestricted, int *count)
{
    for (int i = 0; i < graphSize[u]; i++) {
        int v = graph[u][i];
        if (!visited[v] && !isRestricted[v]) {
            visited[v] = true;
            (*count)++;
            dfs(v, graph, graphSize, visited, isRestricted, count);
        }
    }
}
int reachableNodes(int n, int **edges, int edgesSize, int *edgesColSize, int *restricted, int restrictedSize)
{
    // 创建并初始化受限节点标记数组
    bool *isRestricted = (bool *)malloc(n * sizeof(bool));
    for (int i = 0; i < n; i++) isRestricted[i] = false;
    for (int i = 0; i < restrictedSize; i++) {
        isRestricted[restricted[i]] = true;
    }
    // 如果节点0受限,直接返回0
    if (isRestricted[0]) {
        free(isRestricted);
        return 0;
    }
    // 计算每个节点的度数
    int *degree = (int *)malloc(n * sizeof(int));
    for (int i = 0; i < n; i++) degree[i] = 0;
    for (int i = 0; i < edgesSize; i++) {
        int u = edges[i][0];
        int v = edges[i][1];
        degree[u]++;
        degree[v]++;
    }
    // 创建邻接表
    int **graph = (int **)malloc(n * sizeof(int *));
    int *graphSize = (int *)malloc(n * sizeof(int));
    for (int i = 0; i < n; i++) {
        graph[i] = (int *)malloc(degree[i] * sizeof(int));
        graphSize[i] = 0; // 初始化当前邻居数量
    }
    // 填充邻接表
    for (int i = 0; i < edgesSize; i++) {
        int u = edges[i][0];
        int v = edges[i][1];
        graph[u][graphSize[u]++] = v;
        graph[v][graphSize[v]++] = u;
    }
    // 创建并初始化访问标记数组
    bool *visited = (bool *)malloc(n * sizeof(bool));
    for (int i = 0; i < n; i++) visited[i] = false;
    visited[0] = true;
    int count = 1; // 从节点0开始计数
    dfs(0, graph, graphSize, visited, isRestricted, &count);
    
    // 释放内存
    free(isRestricted);
    free(degree);
    for (int i = 0; i < n; i++) {
        free(graph[i]);
    }
    free(graph);
    free(graphSize);
    free(visited);
    return count;
}

1466. 重新规划路线


c 复制代码
typedef struct {
    int to;         // 邻接节点
    int weight;     // 权值:1表示需要反转,0表示不需要
} Edge;
int minReorder(int n, int **connections, int connectionsSize, int *connectionsColSize)
{
    // 1. 统计每个节点的度数(邻接点数量)
    int *degree = (int*)malloc(n * sizeof(int));
    memset(degree, 0, n * sizeof(int));
    for (int i = 0; i < connectionsSize; i++) {
        int u = connections[i][0];
        int v = connections[i][1];
        degree[u]++;
        degree[v]++;
    }
    // 2. 为邻接表分配空间
    Edge **graph = (Edge **)malloc(n * sizeof(Edge*));
    for (int i = 0; i < n; i++) {
        graph[i] = (Edge *)malloc(degree[i] * sizeof(Edge));
    }
    int *index = (int *)malloc(n * sizeof(int)); 
    memset(index, 0, n * sizeof(int));
    // 3. 构建邻接表(添加正向和反向边)
    for (int i = 0; i < connectionsSize; i++) {
        int u = connections[i][0];
        int v = connections[i][1];
        // 添加正向边:u->v,权值1(需要反转)
        graph[u][index[u]++] = (Edge){v, 1};
        // 添加反向边:v->u,权值0(不需要反转)
        graph[v][index[v]++] = (Edge){u, 0};
    }
    // 4. 使用数组实现BFS队列
    int *queue = (int*)malloc(n * sizeof(int)); // BFS队列
    int head = 0, tail = 0;                     // 队列头尾指针
    int *visited = (int*)malloc(n * sizeof(int));
    memset(visited, 0, n * sizeof(int));
    int res = 0; // 需要反转的边数
    queue[tail++] = 0;
    visited[0] = 1;
    // 5. BFS
    while (head < tail) {
        int u = queue[head++]; // 出队
        for (int i = 0; i < degree[u]; i++) {
            int v      = graph[u][i].to;
            int weight = graph[u][i].weight;
            if (visited[v] == 0) {
                if (weight == 1) {
                    res++; // 需要反转的边
                }
                visited[v] = 1;
                queue[tail++] = v; // 入队
            }
        }
    }
    // 6. 释放资源
    free(degree);
    free(index);
    free(visited);
    free(queue);
    for (int i = 0; i < n; i++) {
        free(graph[i]);
    }
    free(graph);
    return res;
}
相关推荐
一切皆是因缘际会23 分钟前
资源的适配
大数据·人工智能·算法
鲸能云26 分钟前
【智慧能源】源储调售一体化架构与 EMS 滚动调度算法实践 —— 工商业光储收益提升 22% 的技术拆解
算法·架构·能源
双翌视觉34 分钟前
曝光调不对,算法全白费:机器视觉的曝光三态解析
人工智能·算法·计算机视觉
ysu_031443 分钟前
02-单链表完全指南
c语言·数据结构·算法·leetcode
生态学者1 小时前
香港理工大学Nature Communications:沿海塑料际古菌组特征及生态影响
大数据·人工智能·算法·r语言·微信公众平台
ocean21031 小时前
2025-2026年计算机网络面试高频知识点洞察
计算机网络·面试·职场和发展·https·tcp·面试真题·秋招春招
圣保罗的大教堂1 小时前
leetcode 3904. 最小稳定下标 II 中等
leetcode
ly-272531 小时前
IEEE PDF eXpress终稿检测踩坑记录:PDF图片字体未嵌入与LaTeX参考文献编译异常解决方法
服务器·人工智能·算法
代码不停1 小时前
子序列问题
java·算法
黎阳之光2 小时前
AI黑光相机|赋能低空全域感知,筑牢低空经济全天候视觉防线
人工智能·物联网·算法·安全·数字孪生