山海琴音 2023-08-09 22:18 采纳率: 66.7%
浏览 9
已结题

Similar brothers(深搜)

遇到一道卡了我好久的题(向各位请教,望各位能提供一点思路)
有一无向连通图 G(n 个顶点,n - 1条边,点从 1 到 n 依次编号)。当然,你能看出这其实就是一棵树,请找出所有满足以下条件的节点:

该节点不是叶子节点(度不为 0)。
该节点下面所有的子树大小必须相同(如果下面只有一棵子树也默认为相同)。
注意,该树为有根树,你需要先找到它的根才能开始访问其他节点。

输入格式
第一行包含 1 个整数 n。

接下来 n-1 行,每行包含 2 个用空格隔开的正整数 u、v,表示编号为 u 和编号为 v 的点之间有边相连,其中 u 是 v 的父亲节点。

输出格式
输出共 1 行,包含若干个整数,之间用空格隔开,表示为满足题目要求的节点编号。

注意,输出的顺序要按照编号 从小到大 进行输出。

数据范围
对于 30% 的数据,1 < n ≤ 100;

对于 60% 的数据,1 < n ≤ 2000;

对于 100% 的数据,1 < n ≤ 200000

void add (int a, int b) {
    e[idx] = b, ne[idx] = h[a], h[a] = idx ++;
}
void dfs (int u)
{
    size[u] = 1;
    for (int i = h[u]; i != -1; i = ne[i]) {
        int j = e[i];
        if (j == root) continue;
        dfs(j);
        size[u] += size[j];
    }
}

折腾了半天也只弄出了两个函数

  • 写回答

1条回答 默认 最新

  • CSDN-Ada助手 CSDN-AI 官方账号 2023-08-10 08:41
    关注

    【以下回答由 GPT 生成】

    问题已经很清晰了,你需要优化给定的代码,使用深度优先搜索算法来解决问题。问题的目标是找到满足一定条件的节点编号,并按照编号从小到大的顺序进行输出。

    你可以将代码分为两部分来进行优化:添加prompt和实现深度优先搜索算法。

    添加prompt

    为了让chatgpt更好地理解你的问题,请在回答中添加以下prompt:

    问题描述: 给定一个无向连通图G,找出满足一定条件的节点编号。

    条件: 1. 节点不是叶子节点。 2. 节点下面的所有子树大小必须相同。

    输入: - 整数n:表示节点的数量。 - n-1行,每行包含两个用空格隔开的正整数u和v,表示节点u和节点v之间有一条边相连,其中u是v的父亲节点。

    输出: - 若干个整数,用空格隔开,表示满足条件的节点编号,按照编号从小到大的顺序输出。

    数据范围: - 对于30%的数据,1 < n ≤ 100; - 对于60%的数据,1 < n ≤ 2000; - 对于100%的数据,1 < n ≤ 200000。

    实现深度优先搜索算法

    // 声明一个数组用于存储节点的度
    int degree[MAXN];
    
    // 创建一个结构体用于存储图的信息
    struct Graph {
        int n; // 节点数量
        vector<vector<int>> adj; // 邻接表,存储节点的相邻节点
    };
    
    // 初始化图的信息
    void initGraph(Graph& graph, int n) {
        graph.n = n;
        graph.adj.resize(n + 1);
        memset(degree, 0, sizeof(degree));
    }
    
    // 添加边
    void addEdge(Graph& graph, int u, int v) {
        graph.adj[u].push_back(v);
        graph.adj[v].push_back(u);
        degree[u]++;
        degree[v]++;
    }
    
    // 深度优先搜索
    void dfs(const Graph& graph, int u, vector<int>& result) {
        // 遍历节点的相邻节点
        for (int v : graph.adj[u]) {
            // 如果节点v未被访问过且不是根节点
            if (degree[v] > 1 && degree[v] != degree[u]) {
                continue;
            }
    
            // 记录满足条件的节点编号
            result.push_back(v);
    
            // 递归访问子树
            dfs(graph, v, result);
        }
    }
    
    // 主函数
    vector<int> findSimilarNodes(int n, vector<vector<int>>& edges) {
        // 创建并初始化图的信息
        Graph graph;
        initGraph(graph, n);
    
        // 添加边
        for (auto& edge : edges) {
            int u = edge[0];
            int v = edge[1];
            addEdge(graph, u, v);
        }
    
        // 找到根节点
        int root = 1;
        for (int i = 1; i <= n; i++) {
            if (degree[i] > 1) {
                root = i;
                break;
            }
        }
    
        // 进行深度优先搜索
        vector<int> result;
        dfs(graph, root, result);
    
        // 对结果进行排序
        sort(result.begin(), result.end());
    
        return result;
    }
    

    希望以上解决方案能够满足你的需求。如果你有任何问题,请随时向我提问。



    【相关推荐】


    • 你可以参考下这个问题的回答, 看看是否对你有帮助, 链接: https://ask.csdn.net/questions/7743683
    • 除此之外, 这篇博客: 单素数判断(根号n后再优化)和俄罗斯农民乘法(带证明),以及埃筛的证明中的 简单解释下普遍大家都知道的(给新手),就是为啥只到根号n。最开始其实终止条件是到n/2的,很简单嘛,因为n/2之后不可能存在n的因子,因为最小的因子2乘上一个任何一个大于n/2的数肯定比n大,所以之后不存在因子。那为啥能筛到根号n呢,是因为根号n的平方是n本身,根号n后面如果存在n的因子a,那么一定能在n之前找到n/a这个因子,只要有因子就不是素数了,所以没必要反复筛,前面筛完就已经知道不是素数了 部分也许能够解决你的问题。

    如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 系统已结题 8月26日
  • 已采纳回答 8月18日
  • 修改了问题 8月9日
  • 修改了问题 8月9日
  • 展开全部

悬赏问题

  • ¥15 船舶旋回实验matlab
  • ¥30 SQL 数组,游标,递归覆盖原值
  • ¥15 为什么我的数据接收的那么慢呀有没有完整的 hal 库并 代码呀有的话能不能发我一份并且我用 printf 函数显示处理之后的数据,用 debug 就不能运行了呢
  • ¥15 有关于推荐系统jupyter
  • ¥20 gitlab 中文路径,无法下载
  • ¥15 用动态规划算法均分纸牌
  • ¥30 udp socket,bind 0.0.0.0 ,如何自动选取用户访问的服务器IP来回复数据
  • ¥15 关于树的路径求解问题
  • ¥15 yolo在训练时候出现File "D:\yolo\yolov5-7.0\train.py"line 638,in <module>
  • ¥30 戴尔inspiron独显直连