1 条题解

  • 0
    @ 2025-5-25 18:27:01

    这段代码实现了判断一个图是否为**毛毛虫树(Caterpillar Tree)**的算法。毛毛虫树是一种特殊的树,其结构可以抽象为一条主干路径(脊椎),所有叶子节点(度数为1的节点)直接连接到这条路径上。

    算法原理

    毛毛虫树的定义
    毛毛虫树是一棵树,且满足:所有非叶子节点(度数≥2)构成一条简单路径(称为脊椎),所有叶子节点直接连接到这条路径上。

    判断策略
    必要条件:输入图必须是一棵树(即连通且边数为n-1)。
    核心思想:从任意一个非叶子节点出发进行DFS,尝试遍历所有非叶子节点形成的路径,并标记所有可达的叶子节点。若所有节点都被标记,则该树是毛毛虫树。

    DFS遍历规则
    当遍历到一个非叶子节点时,若其度数≥3,则停止继续深入(因为脊椎路径上的节点度数最多为2,度数≥3的节点会导致路径分叉)。
    若遇到叶子节点(度数为1),直接标记该节点但不继续递归。

    关键步骤

    预处理
    输入图必须是树(边数为n-1),否则直接判定不是毛毛虫树。

    DFS遍历
    从任意一个非叶子节点出发,递归遍历所有非叶子节点,并标记遇到的叶子节点。
    若DFS过程中某个节点的度数≥3,停止从该节点继续深入,避免遍历到非脊椎路径。

    结果检查
    若所有节点都被DFS标记,则该树是毛毛虫树;否则不是。

    总结

    该算法通过DFS遍历脊椎路径并验证所有叶子节点的连接性,高效判断一个树是否为毛毛虫树。其核心在于利用脊椎路径的线性结构特性,确保所有非叶子节点形成一条简单路径。

    #include<iostream>
    #include <cstring> // 引入 memset
    #include <cstdio>  // 引入 scanf 和 printf
    using namespace std;
    
    const int maxN = 128;
    int g[maxN][maxN];
    int d[maxN], ok[maxN], vis[maxN];
    int n;
    
    void dfs(int u) {
        int v, cnt = 0;
        ok[u] = 1;
        vis[u] = 1;
        for (v = 1; v <= n; ++v)
            if (g[u][v] == 1 && d[v] > 1) {
                ++cnt;
                if (cnt == 3)
                    return;
            }
        for (v = 1; v <= n; ++v)
            if (g[u][v] == 1 && vis[v] == 0) {
                if (d[v] == 1) {
                    ok[v] = 1;
                    continue;
                } else
                    dfs(v);
            }
    }
    
    int main() {
        int cases = 0;
        while (scanf("%d", &n) == 1 && n) { // 使用 scanf 读取输入
            int m;
            memset(g, 0, sizeof(g));
            memset(d, 0, sizeof(d));
            memset(ok, 0, sizeof(ok));
            memset(vis, 0, sizeof(vis));
            scanf("%d", &m); // 读取边数
            for (int i = 0; i < m; ++i) {
                int a, b;
                scanf("%d%d", &a, &b); // 读取边的两个顶点
                g[a][b] = g[b][a] = 1;
                ++d[a];
                ++d[b];
            }
            if (m != n - 1) { // 非树结构直接判断
                printf("Graph %d is not a caterpillar.\n", ++cases); // 使用 printf 输出
                continue;
            }
            int i, flag = 0;
            for (i = 1; i <= n; ++i)
                if (d[i] > 1)
                    break; // 找到第一个度数大于1的节点
            dfs(i); // 从该节点开始DFS
            for (i = 1; i <= n; ++i)
                if (ok[i] != 1) // 检查所有节点是否被标记
                    flag = 1;
            if (flag == 1)
                printf("Graph %d is not a caterpillar.\n", ++cases);
            else
                printf("Graph %d is a caterpillar.\n", ++cases);
        }
        return 0;
    }
    
    • 1

    信息

    ID
    2311
    时间
    1000ms
    内存
    256MiB
    难度
    5
    标签
    递交数
    2
    已通过
    1
    上传者