首页 > 其他分享 >生成一棵树

生成一棵树

时间:2024-08-07 10:54:25浏览次数:12  
标签:std return int Tree 一棵树 生成 ++ dis

可以说包含大多数可以叉人的树。

code:

#include <bits/stdc++.h>

using u32 = unsigned;
using i64 = long long;
using u64 = unsigned long long;

std::mt19937 g(static_cast<u32>(std::chrono::system_clock::now().time_since_epoch().count()));
const int Rand(int l, int r) {
    return g() % (r - l + 1) + l;
}
struct Tree {
    int n;
    std::vector<std::array<int, 2>> edges;
    Tree() {
        n = 0;
    }
    Tree(int _n) {
        n = _n;
        edges.clear();
    }
    void addEdge(int u, int v) {
        edges.push_back({u, v});
    }
    void printEdges(int beg = 1) {
        for (auto [u, v] : edges) {
            std::cout << u + beg << " " << v + beg << "\n";
        }
    }
} ;
void Merge(Tree &a, const Tree &b, int u, int v) {
    const int n = a.n;
    a.n += b.n;
    for (auto [u, v] : b.edges) {
        u += n, v += n;
        a.addEdge(u, v);
    }
    a.addEdge(u, v + n);
}
class TreeGenerator {
public:
    Tree Shuffle(Tree t) {
        std::vector<int> p(t.n);
        iota(p.begin(), p.end(), 0);
        shuffle(p.begin(), p.end(), g);
        for (auto& [u, v] : t.edges) {
            u = p[u];
            v = p[v];
            if (Rand(0, 1)) {
                std::swap(u, v);
            }
        }
        shuffle(t.edges.begin(), t.edges.end(), g);
        return t;
    }
    Tree Random(int n) {
        Tree t(n);
        for (int i = 1; i < n; ++i) {
            t.addEdge(i, Rand(0, i - 1));
        }
        return t;
    }
    Tree Random(int n, int d) {
        Tree t(n);
        for (int i = 1; i < n; ++i) {
            t.addEdge(i, Rand(std::max(0, i - d), i - 1));
        }
        return t;
    }
    Tree PruferToTree(std::vector<int> p) {
        int n = p.size() + 2;
        Tree t(n);

        std::vector<int> deg(n, 1);
        std::set<int> s;
        for (int i = 0; i < n - 2; ++i) {
            ++deg[p[i]];
        }
        for (int i = 0; i < n; ++i) {
            if (deg[i] == 1) {
                s.insert(i);
            }
        }

        for (int i = 0; i < n - 2; ++i) {
            int u = p[i], v = *s.begin();
            t.addEdge(u, v);
            s.erase(s.begin());
            --deg[u], --deg[v];

            if (deg[u] == 1) {
                s.insert(u);
            }
        }
        t.addEdge(*s.begin(), *--s.end());

        return t;
    }
    Tree RandomPruffer(int n) {
        std::vector<int> p(n - 2);
        for (int i = 0; i < n; ++i) {
            p[i] = Rand(0, n - 1);
        }
        return PruferToTree(p);
    }
    Tree Chain(int n) {
        return Dandelion(n, 1);
    }
    Tree Star(int n) {
        return Dandelion(n, n - 1);
    }
    Tree Binary(int n) {
        Tree t(n);
        std::vector<int> deg(n, 1), p(n - 2);
        for (int i = 0; i < n - 2; ++i) {
            int u = Rand(0, n - 1);
            while (deg[u] == 3) {
                u = Rand(0, n - 1);
            }
            p[i] = u;
        }
        return PruferToTree(p);
    }
    Tree CompleteBinary(int n) {
        assert(n & 1);
        Tree t(n);
        for (int i = 0; i < n - 1; ++i) {
            t.addEdge(i / 2, i + 1);
        }
        return t;
    }
    Tree Dandelion(int n, int d) {
        assert(d < n);
        Tree t(n);
        for (int i = 1; i <= d; ++i) {
            t.addEdge(i, 0);
        }
        for (int i = d + 1; i < n; ++i) {
            t.addEdge(i, i - d);
        }
        return t;
    }
    Tree Broom(int n, int d) {
        assert(d < n);
        Tree t(n);
        for (int i = 1; i <= d; ++i) {
            t.addEdge(i - 1, i);
        }
        for (int i = d + 1; i < n; ++i) {
            t.addEdge(0, i);
        }
        return t;
    }
    Tree Worm(int n) {
        Tree t(n);
        for (int i = 1; i < n; ++i) {
            if (i & 1) {
                t.addEdge(i - 1, i);
            } else {
                t.addEdge(i - 2, i);
            }
        }
        return t;
    }
} ;

int FindDiameter(Tree t) {
    int n = t.n;
    std::vector<std::vector<int>> adj(n);
    for (auto [u, v] : t.edges) {
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
    auto bfs = [&](int st) {
        std::queue<int> q;
        std::vector<int> dis(n, -1);
        dis[st] = 0;
        q.push(st);

        while (!q.empty()) {
            int u = q.front();
            q.pop();

            for (auto v : adj[u]) {
                if (dis[v] == -1) {
                    dis[v] = dis[u] + 1;
                    q.push(v);
                }
            }
        }

        return std::make_pair(max_element(dis.begin(), dis.end()) - dis.begin(), dis);
    } ;
    int a = bfs(0).first;
    auto [b, dis] = bfs(a);

    return dis[b];
}

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);

    /*下面展示了一下将若干个大小为 1E3 的菊花图的根节点拼成一条链*/
    TreeGenerator gen;
    int n = 1E3;
    std::vector<Tree> tr(n);
    for (int i = 0; i < n; ++i) {
        tr[i] = gen.Star(1E3);
    }
    Tree t = tr[0];
    for (int i = 1; i < n; ++i) {
        Merge(t, tr[i], t.n - 1E3, 0);
    }
    std::cout << "n: " << t.n << ", d: " << FindDiameter(t) << "\n";
    t.printEdges();

    return 0;
}

标签:std,return,int,Tree,一棵树,生成,++,dis
From: https://www.cnblogs.com/CTHOOH/p/18346631

相关文章

  • ChatMoneyAI挑战高考英语作文,3秒即生成
    本文由ChatMoney团队出品在科技日新月异的今天,人工智能(AI)已不再是遥不可及的未来科技,而是逐渐融入我们日常生活的实用工具。从智能语音助手到自动驾驶汽车,从智能家居系统到精准医疗诊断,AI技术正以其强大的计算能力和数据分析能力,改变着我们的工作方式、生活方式乃至思维方式。......
  • 使用 Python 中的 Matplotlib 和时间序列索引生成奇怪的图
    我正在尝试使用Python中的Matplotlib绘制一些时间序列数据,但生成的图看起来很奇怪,我不明白为什么。这是我正在使用的代码:filtered_df=df.loc[(df.index>'2010-01-01')&(df.index<='2010-01-08')]#Plottingthedatafig,axs=plt.subplots(1,1,figsize=(12,......
  • Transformer在生成细胞数据上的应用
    来自:scTranslator:Apre-trainedlargegenerativemodelfortranslatingsingle-celltranscriptometoproteome工程地址:https://github.com/TencentAILabHealthcare/scTranslator在scTranslator中,有3个阶段:pairedbulk上监督学习,pairedsc上监督学习,scRNA上推理。前......
  • Python 中的生成器函数有什么作用及如何使用?
    生成器函数是一种特殊的函数,可以在迭代过程中动态生成值,而不是一次性返回所有值。它的作用有以下几点:节省内存:生成器函数一次只生成一个值,并在生成后立即释放内存,这样可以减小内存的占用,特别是在处理大数据集时非常有用。延迟计算:生成器函数可以按需生成值,只在需要的时......
  • 概率生成函数学习
    https://www.cnblogs.com/zzctommy/p/14256844.htmlhttps://www.cnblogs.com/HenryHuang-Never-Settle/p/14702997.html概率生成函数,设多项式\(F(x)=\sumP(X=i)x^i\)。则:\(F(1)=1\);\(E(x)=F'(1)\);\(E(x^{\underline{k}})=F^{(k)}(1)\),\(k\)阶导。\(......
  • mybatis插件代码生成。
    mybatis插件代码生成。第一步连接数据库:第二步,选择数据库表:第三步,进行配置选择第四步、就生成了有关于表的实体类和其他的表数据。第一步连接数据库:在右边,拉出数据库的操作栏输入用户名密码,然后点击测试第二步,选择数据库表:第三步,进行配置选择一定要对照图片来......
  • 代码随想录算法训练营第59天 | 最小生成树
    53.寻宝https://kamacoder.com/problempage.php?pid=1053prim算法精讲https://www.programmercarl.com/kamacoder/0053.寻宝-prim.htmlkruskal算法精讲https://www.programmercarl.com/kamacoder/0053.寻宝-Kruskal.html题目描述在世界的某个区域,有一些分散的神秘岛屿,每......
  • Python实现猜数字游戏:带提示范围和随机生成数字功能
    概述这篇文章将介绍一个使用Python编写的简单猜数字游戏。该游戏会随机生成一个1到10之间的数字,然后用户需要猜测这个数字。每次猜测后,程序会根据用户的输入调整提示范围,直到用户猜中为止。代码实现首先,导入必要的模块并生成一个随机数:importrandom#生成1-10之间的随机......
  • 利用chatgpt3.5/4.0生成一个generator,完成杨辉三角
    deftriangles():row=[1]whileTrue:yieldrowrow=[sum(x)forxinzip([0]+row,row+[0])]#期待输出:#[1]#[1,1]#[1,2,1]#[1,3,3,1]#[1,4,6,4,1]#[1,5,10,10,5,1]#[1,6,15,20,15,6,1]#[1,7,......
  • 看片神器,将本地视频通过AI自动生成字幕及翻译字幕
    迈信达音视频字幕软件(MaixindaSubtitle)是一款专注于自动化视频转录文本、字幕制作、字幕翻译的AI自动化字幕软件。通过AI一键生成本地音频与视频的字幕文件,及翻译字幕内容。使用AI提取音视频对话内容后翻译、生成字幕文件,可以低成本并高效地将任意语言的视频、音频转录并翻译为目......