0

0

打印有向图中不属于任何循环的节点

王林

王林

发布时间:2023-09-13 22:25:02

|

1191人浏览过

|

来源于tutorialspoint

转载

打印有向图中不属于任何循环的节点

BibiGPT-哔哔终结者
BibiGPT-哔哔终结者

B站视频总结器-一键总结 音视频内容

下载

在协调图中,识别不属于任何循环的集线器对于不同的应用程序至关重要。这些中心构建了非循环子图的基础,并在理解一般图表结构方面发挥着重要作用。通过使用有效的图表交叉计算,例如 Profundity First Hunt (DFS) 或 Tarjan 对紧密关联部件的计算,我们可以毫不费力地决定并打印不参与任何循环的集线器。这些方法保证了没有循环合作的中心的特色,为图表的非循环部分提供了重要的知识,并支持与图表相关的不同批判性思维情况。

使用的方法

  • 带循环检测的深度优先搜索 (DFS)

  • Tarjan 的强连通分量算法

带循环检测的深度优先搜索 (DFS)

在此方法中,我们使用深度优先追踪 (DFS) 来导航协调图表并区分途中的周期。我们标记访问过的中心并保留一份清单,以便以持续的 DFS 方式跟踪中心。如果我们遇到后沿(以持续的 DFS 方式到达集线器的边缘),我们会区分一个周期。在 DFS 结束时,正在进行的 DFS 方式中的中心对于一个周期将很重要。不采用持续 DFS 方式的集线器不属于任何循环,可以打印。

算法

  • 在图表上从每个未访问过的中心开始进行深度首次狩猎 (DFS)。

  • 在 DFS 期间,标记访问过的集线器并将其添加到正在进行的 DFS 路径列表中。

  • 如果我们遇到后沿(当前 DFS 方式中到集线器的边缘),我们会区分一个周期,并将当前 DFS 方式中的所有集线器标记为周期的一部分。

  • 当集线器的 DFS 完成后,将其从正在进行的 DFS 路径列表中删除。

  • 完成所有轮毂的 DFS 后,不属于任何循环的轮毂将保持不变,我们可以打印它们。

示例

#include 
#include 

class Graph {
public:
   Graph(int numVertices);
   void addEdge(int src, int dest);
   void DFS();
private:
   void DFSUtil(int v, std::vector& visited, std::vector& dfsPath);
   int numVertices;
   std::vector> adjList;
};

Graph::Graph(int numVertices) : numVertices(numVertices) {
   adjList.resize(numVertices);
}

void Graph::addEdge(int src, int dest) {
   adjList[src].push_back(dest);
}

void Graph::DFSUtil(int v, std::vector& visited, std::vector& dfsPath) {
   visited[v] = true;
   dfsPath.push_back(v);

   for (int neighbor : adjList[v]) {
      if (!visited[neighbor]) {
         DFSUtil(neighbor, visited, dfsPath);
      }
      else {
         std::cout << "Cycle found: ";
         for (size_t i = 0; i < dfsPath.size(); ++i) {
            if (dfsPath[i] == neighbor) {
               while (i < dfsPath.size()) {
                  std::cout << dfsPath[i] << " ";
                  ++i;
               }
               break;
            }
         }
         std::cout << std::endl;
      }
   }

   dfsPath.pop_back();
}

void Graph::DFS() {
   std::vector visited(numVertices, false);
   std::vector dfsPath;

   for (int i = 0; i < numVertices; ++i) {
      if (!visited[i]) {
         DFSUtil(i, visited, dfsPath);
      }
   }
}

int main() {
   Graph graph(6);
   graph.addEdge(0, 1);
   graph.addEdge(1, 2);
   graph.addEdge(2, 3);
   graph.addEdge(3, 4);
   graph.addEdge(4, 1);
   graph.addEdge(4, 5);
   
   std::cout << "DFS traversal with cycle detection:\n";
   graph.DFS();

   return 0;
}

输出

DFS traversal with cycle detection:
Cycle found: 1 2 3 4 

Tarjan 的强连通分量算法

Tarjan 的计算是一种强大的计算,用于追踪协调图中所有重点关联的部分。明确关联的部分是集线器的子集,其中子集中的任意两个集线器之间存在协调方式。不属于任何紧密关联部件的轮毂也不属于任何循环。通过查找重点关联的零件,我们可以识别不属于任何循环的轮毂并打印它们\

算法

  • 将 Tarjan 的计算应用于引导图,以追踪所有重点关联的部分。

  • 在追踪所有重要关联部分后,区分对于紧密关联部分至关重要的中心。

  • 不属于任何明确关联部件的集线器不属于任何循环,并且可以打印。

  • 这两种方法确实区分并打印了不属于协调图表中任何周期的中心。 DFS 方法提供了更简单且更直接的执行,而 Tarjan 的计算更复杂,但提供了有关重点关联部分的额外数据,这对于特定的图表相关任务很有帮助。方法的决定取决于具体的需要和主要紧迫问题的背景。

示例

#include 
#include 
#include 
#include 
using namespace std;

class Graph {
   int V;
   vector> adj;
   vector visited;
   vector disc, low;
   stack st;
   vector> SCCs;
   vector essentialNodes;

public:
   Graph(int V) : V(V) {
      adj.resize(V);
      visited.resize(V, false);
      disc.resize(V, -1);
      low.resize(V, -1);
      essentialNodes.resize(V, true);
   }

   void addEdge(int u, int v) {
      adj[u].push_back(v);
   }

   void tarjanDFS(int u) {
      static int time = 0;
      disc[u] = low[u] = ++time;
      st.push(u);
      visited[u] = true;

      for (int v : adj[u]) {
         if (disc[v] == -1) {
            tarjanDFS(v);
            low[u] = min(low[u], low[v]);
         } else if (visited[v]) {
            low[u] = min(low[u], disc[v]);
         }
      }

      if (low[u] == disc[u]) {
         vector SCC;
         int v;
         do {
            v = st.top();
            st.pop();
            SCC.push_back(v);
            visited[v] = false;
         } while (v != u);

         SCCs.push_back(SCC);
      }
   }

   void tarjan() {
      for (int i = 0; i < V; ++i) {
         if (disc[i] == -1) {
            tarjanDFS(i);
         }
      }
   }

   void identifyEssentialNodes() {
      for (const vector& SCC : SCCs) {
         for (int v : SCC) {
            for (int u : adj[v]) {
               if (find(SCC.begin(), SCC.end(), u) == SCC.end()) {
                  essentialNodes[u] = false;
               }
            }
         }
      }
   }

   void printEssentialNodes() {
      cout << "Essential Nodes for Each SCC:\n";
      for (int i = 0; i < V; ++i) {
         if (essentialNodes[i]) {
            cout << i << " ";
         }
      }
      cout << endl;
   }
};

int main() {
   Graph g(6);
   g.addEdge(0, 1);
   g.addEdge(1, 2);
   g.addEdge(2, 0);
   g.addEdge(1, 3);
   g.addEdge(3, 4);
   g.addEdge(4, 5);
   g.addEdge(5, 3);

   g.tarjan();
   g.identifyEssentialNodes();
   g.printEssentialNodes();

   return 0;
}

输出

Essential Nodes for Each SCC:
0 1 2 4 5

结论

这两种方法确实解决了识别不属于协调图表中任何周期的中心的问题。 DFS 方法易于执行,并且不需要太多额外的信息结构。另一方面,Tarjan 的计算提供了有关重点关联部分的额外数据,这在特定情况下可能会有所帮助。

两种方法之间的决定取决于问题的特定先决条件以及对经过与周期无关的区分中心的额外数据的要求。一般来说,如果唯一的目标是找到不属于任何循环的集线器,则 DFS 方法可能会因其简单性而受到青睐。尽管如此,如果需要进一步检查重点相关部分,Tarjan 的计算可能是一个重要的工具。这两种方法提供了熟练的安排,并且可以根据协调图表的属性和考试的理想结果进行调整

全能打印神器
全能打印神器

全能打印神器是一款非常好用的打印软件,可以在电脑、手机、平板电脑等设备上使用。支持无线打印和云打印,操作非常简单,使用起来也非常方便,有需要的小伙伴快来保存下载体验吧!

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
页面置换算法
页面置换算法

页面置换算法是操作系统中用来决定在内存中哪些页面应该被换出以便为新的页面提供空间的算法。本专题为大家提供页面置换算法的相关文章,大家可以免费体验。

407

2023.08.14

俄罗斯Yandex引擎入口
俄罗斯Yandex引擎入口

2026年俄罗斯Yandex搜索引擎最新入口汇总,涵盖免登录、多语言支持、无广告视频播放及本地化服务等核心功能。阅读专题下面的文章了解更多详细内容。

177

2026.01.28

包子漫画在线官方入口大全
包子漫画在线官方入口大全

本合集汇总了包子漫画2026最新官方在线观看入口,涵盖备用域名、正版无广告链接及多端适配地址,助你畅享12700+高清漫画资源。阅读专题下面的文章了解更多详细内容。

35

2026.01.28

ao3中文版官网地址大全
ao3中文版官网地址大全

AO3最新中文版官网入口合集,汇总2026年主站及国内优化镜像链接,支持简体中文界面、无广告阅读与多设备同步。阅读专题下面的文章了解更多详细内容。

79

2026.01.28

php怎么写接口教程
php怎么写接口教程

本合集涵盖PHP接口开发基础、RESTful API设计、数据交互与安全处理等实用教程,助你快速掌握PHP接口编写技巧。阅读专题下面的文章了解更多详细内容。

2

2026.01.28

php中文乱码如何解决
php中文乱码如何解决

本文整理了php中文乱码如何解决及解决方法,阅读节专题下面的文章了解更多详细内容。

4

2026.01.28

Java 消息队列与异步架构实战
Java 消息队列与异步架构实战

本专题系统讲解 Java 在消息队列与异步系统架构中的核心应用,涵盖消息队列基本原理、Kafka 与 RabbitMQ 的使用场景对比、生产者与消费者模型、消息可靠性与顺序性保障、重复消费与幂等处理,以及在高并发系统中的异步解耦设计。通过实战案例,帮助学习者掌握 使用 Java 构建高吞吐、高可靠异步消息系统的完整思路。

8

2026.01.28

Python 自然语言处理(NLP)基础与实战
Python 自然语言处理(NLP)基础与实战

本专题系统讲解 Python 在自然语言处理(NLP)领域的基础方法与实战应用,涵盖文本预处理(分词、去停用词)、词性标注、命名实体识别、关键词提取、情感分析,以及常用 NLP 库(NLTK、spaCy)的核心用法。通过真实文本案例,帮助学习者掌握 使用 Python 进行文本分析与语言数据处理的完整流程,适用于内容分析、舆情监测与智能文本应用场景。

24

2026.01.27

拼多多赚钱的5种方法 拼多多赚钱的5种方法
拼多多赚钱的5种方法 拼多多赚钱的5种方法

在拼多多上赚钱主要可以通过无货源模式一件代发、精细化运营特色店铺、参与官方高流量活动、利用拼团机制社交裂变,以及成为多多进宝推广员这5种方法实现。核心策略在于通过低成本、高效率的供应链管理与营销,利用平台社交电商红利实现盈利。

122

2026.01.26

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号