leetcode 310 最小高度树(拓扑排序变形)

题目描述:

  对于一个具有树特征的无向图,我们可选择任何一个节点作为根。图因此可以成为树,在所有可能的树中,具有最小高度的树被称为最小高度树。给出这样的一个图,写出一个函数找到所有的最小高度树并返回他们的根节点。

题解:

  首先要确定一个结论,最小高度树最多只有两个。可以用反证法证明,假设有n(n>=3)个最小高度树,那么这三个树的高度要一致。在这三个节点相邻的情况下(不相邻的情况一定不存在,可以推一下),分别取这三个节点为根节点的树的高度不一致,与假设相悖。

  再就是有向图的一个拓扑排序:

  step1:把度为1的点去掉(注意,一次操作需要把所有度为1的点去掉)

  step2:重复step1,直到剩下的节点个数小于等于2

AC代码:

  

class Solution {
public:
    //
    vector<int> findMinHeightTrees(int n, vector<vector<int>>& edges) {
        for(int i=0;i<n;i++)
        {
            edge[i].clear();
            degree[i] = 0;
        }
        int edge_Len = edges.size();
        for(int i=0;i<edge_Len;i++)
        {
            edge[edges[i][0]].push_back(edges[i][1]);
            edge[edges[i][1]].push_back(edges[i][0]);
            degree[edges[i][0]]++;
            degree[edges[i][1]]++;
        }

        vector<int> ans;
        queue<int> que;
        for(int i=0;i<n;i++)
        {
            if(degree[i] == 1 || degree[i] == 0) que.push(i);
        }
        int cnt = n;
        // 剩余节点的个数
        while(cnt>2)
        {
            // 把所有度为1的点都处理掉
            while(!que.empty())
            {
                int now = que.front();
                que.pop();
                cnt--;
                degree[now] = -1;
                int Len  = edge[now].size();
                for(int i=0;i<Len;i++)
                {
                    int next= edge[now][i];
                    degree[next]--;
                }
            }
            for(int i=0;i<n;i++)
            {
                if(degree[i] == 1 || degree[i] == 0) que.push(i);
            }
        }
        while(!que.empty())
        {
            int now = que.front();
            que.pop();
            ans.push_back(now);
        }
        return ans;
    }

private:
    vector<int> edge[10010];
    int degree[10010];

}; 

原文地址:https://www.cnblogs.com/z1141000271/p/12622884.html

时间: 2024-11-08 13:10:14

leetcode 310 最小高度树(拓扑排序变形)的相关文章

leetcode.310最小高度树

对于一个具有树特征的无向图,我们可选择任何一个节点作为根.图因此可以成为树,在所有可能的树中,具有最小高度的树被称为最小高度树.给出这样的一个图,写出一个函数找到所有的最小高度树并返回他们的根节点. 格式 该图包含 n 个节点,标记为 0 到 n - 1.给定数字 n 和一个无向边 edges 列表(每一个边都是一对标签). 你可以假设没有重复的边会出现在 edges 中.由于所有的边都是无向边, [0, 1]和 [1, 0] 是相同的,因此不会同时出现在 edges 里. 示例 1: 输入:

[LeetCode] Minimum Height Trees 最小高度树

For a undirected graph with tree characteristics, we can choose any node as the root. The result graph is then a rooted tree. Among all possible rooted trees, those with minimum height are called minimum height trees (MHTs). Given such a graph, write

bzoj 3832: [Poi2014]Rally(线段树+拓扑排序)

3832: [Poi2014]Rally Time Limit: 20 Sec  Memory Limit: 128 MBSec  Special Judge Submit: 113  Solved: 56 [Submit][Status][Discuss] Description An annual bicycle rally will soon begin in Byteburg. The bikers of Byteburg are natural long distance cyclis

BZOJ_3012_[Usaco2012 Dec]First!_trie树+拓扑排序

题意: 给定n个总长不超过m的互不相同的字符串,现在你可以任意指定字符之间的大小关系.问有多少个串可能成为字典 序最小的串,并输出这些串.n <= 30,000 , m <= 300,000 分析: 首先不考虑大小关系,如果一个串是另一个串的前缀,那么另一个串一定不能成为字典序最小的串,我们可以用trie树很好的解决. 考虑前缀相同的情况,这个串在前缀后的字符应该和含有相同前缀的串在前缀后的字符有明确的大小关系,根据这个大小关系连边,我们用拓扑排序判断是否矛盾. 以上都满足则可以成为字典序最小

HDU5638 / BestCoder Round #74 (div.1) 1003 Toposort 线段树+拓扑排序

Toposort 问题描述 给出nn个点mm条边的有向无环图. 要求删掉恰好kk条边使得字典序最小的拓扑序列尽可能小. 输入描述 输入包含多组数据. 第一行有一个整数TT, 表示测试数据组数. 对于每组数据: 第一行包含3个整数nn, mm和kk (1 \le n \le 100000, 0 \le k \le m \le 200000)(1≤n≤100000,0≤k≤m≤200000), 表示图中结点数目, 图中边的数目以及要删的边数. 接下来mm行, 每行包含两个整数u_iu?i?? and

LeetCode 210. Course Schedule II(拓扑排序-求有向图中是否存在环)

和LeetCode 207. Course Schedule(拓扑排序-求有向图中是否存在环)类似. 注意到,在for (auto p: prerequistites)中特判了输入中可能出现的平行边或自环. 代码: class Solution { public: vector<int> findOrder(int numCourses, vector<pair<int, int>>& prerequisites) { // [0, {1, 2, 3}], me

Codeforces Round #363 Fix a Tree(树 拓扑排序)

先做拓扑排序,再bfs处理 #include<cstdio>#include<iostream>#include<cstdlib>#include<cstring>#include<string>#include<algorithm>#include<map>#include<stack>#include<queue>#include<vector>#include<cmath&g

LeetCode 207. Course Schedule(拓扑排序)

题目 There are a total of n courses you have to take, labeled from 0 to n - 1. Some courses may have prerequisites, for example to take course 0 you have to first take course 1, which is expressed as a pair: [0,1] Given the total number of courses and

[CSP-S模拟测试]:Permutation(线段树+拓扑排序+贪心)

题目描述 你有一个长度为$n$的排列$P$与一个正整数$K$你可以进行如下操作若干次使得排列的字典序尽量小对于两个满足$|i−j|\geqslant K$且$|P_i−P_j|=1$的下标$i$与$j$,交换$P_i$与$P_j$ 输入格式 第一行包括两个正整数$n$与$K$第二行包括$n$个正整数,第$i$个正整数表示$P_i$ 输出格式 输出一个新排列表示答案输出共$n$行,第$i$行表示$P_i$ 样例 样例输入: 8 34 5 7 8 3 1 2 6 样例输出: 12675348 数据范