0

0

给定图形删除给定的Q个顶点后的连通分量数量

WBOY

WBOY

发布时间:2023-09-14 13:13:02

|

1213人浏览过

|

来源于tutorialspoint

转载

给定图形删除给定的q个顶点后的连通分量数量

删除 Q 个指定顶点后,图中剩余顶点创建的断开子图的数量由连通分量的计数表示。各个组件之间没有边缘连接;相反,每个连接的组件都由通过边连接的顶点的集合组成。由于 Q 顶点的移除,一些顶点可能会变得孤立,导致连接崩溃并形成新的组件。该方法旨在确定最终会有多少个不相连的子图。许多应用程序,包括网络分析、社交网络研究和优化方法,都需要了解连接组件的数量。

使用的方法

  • Kosaraju 算法

  • 基于矩阵的方法

Kosaraju算法

从图中删除 Q 个指定顶点后,Kosaraju 算法用于确定网络中链接组件的数量。它分两次使用深度优先搜索 (DFS)。它在第一遍中研究原始图以获得每个顶点的“完成时间”。在第二遍中,图被转置(所有边的方向都反转),并且从完成时间最长的顶点开始,将 DFS 应用于变换后的图。该方法确定更改图中的链接组件的数量,通过在过程中忽略删除的 Q 顶点来暴露顶点删除后断开的子图的数量。

算法

  • 要存储初始 DFS 通道的顶点,请创建一个空堆栈。

  • 在原始图上,运行第一个 DFS 遍历:

    使用 DFS 从未探索的顶点开始探索连接的顶点的组件。

    当所有顶点的周围的顶点已被访问过,Mark 访问该顶点并将其压入堆栈。

  • 反转每条边的方向以转置图形。

  • 对于第二次 DFS 遍历,创建一个布尔数组来跟踪访问过的顶点。

  • 通过第二次 DFS 遍历运行修改后的图:

    从堆栈中依次删除每个顶点。

    使用 DFS 探索顶点的相关组件(如果没有)没有被访问或破坏(不在Q中)。在整个过程中,Mark 访问了顶点。

  • 移除 Q 个顶点后,连通分量的计数等于调用第二个 DFS 的次数。

    玄鲸Timeline
    玄鲸Timeline

    一个AI驱动的历史时间线生成平台

    下载
  • 删除 Q 个顶点后,该过程会生成网络中连通分量的数量。

示例

#include 
#include 
#include 
using namespace std;

void dfs1(int vertex, vector>& graph, vector& visited, stack& stk) {
    visited[vertex] = true;
    for (int neighbor : graph[vertex]) {
        if (!visited[neighbor])
            dfs1(neighbor, graph, visited, stk);
    }
    stk.push(vertex);
}

void dfs2(int vertex, vector>& transpose_graph, vector& visited) {
    visited[vertex] = true;
    for (int neighbor : transpose_graph[vertex]) {
        if (!visited[neighbor])
            dfs2(neighbor, transpose_graph, visited);
    }
}

int kosaraju(int N, vector>& graph, vector>& transpose_graph, vector& Q) {
    vector visited(N + 1, false);
    stack stk;

    for (int i = 1; i <= N; i++) {
        if (!visited[i])
            dfs1(i, graph, visited, stk);
    }

    fill(visited.begin(), visited.end(), false);

    for (int i = 0; i < Q.size(); i++) {
        visited[Q[i]] = true;
    }

    int count = 0;
    while (!stk.empty()) {
        int vertex = stk.top();
        stk.pop();
        if (!visited[vertex]) {
            dfs2(vertex, transpose_graph, visited);
            count++;
        }
    }

    return count;
}

int main() {
    int N = 7; 
    int M = 8; 
    int E = 2; 

    vector> graph(N + 1);
    vector> transpose_graph(N + 1);

    vector> edges = {{1, 2}, {2, 3}, {3, 1}, {2, 4}, {4, 5}, {5, 6}, {6, 4}, {7, 6}};

    for (const auto& edge : edges) {
        int u = edge.first;
        int v = edge.second;
        graph[u].push_back(v);
        transpose_graph[v].push_back(u);
    }

    vector Q = {3, 4};

    int result = kosaraju(N, graph, transpose_graph, Q);
    cout << result << endl;

    return 0;
}

输出

5

基于矩阵的方法

邻接矩阵或邻接列表用于表示基于矩阵的方法中的图。然后从矩阵中删除 Q 个指定的顶点。然后,通过使用图遍历算法(例如深度优先搜索(DFS)或广度优先搜索(BFS))来确定更改的图的连接组件的数量。记录已遍历的顶点以防止重新处理。删除 Q 个顶点后图中连通分量的计数对应于遍历方法运行的次数。对于不同的图分析和网络相关应用,该方法可以有效地计算链接组件计数。

算法

  • 使用邻接矩阵或邻接表来表示图。

  • 修改图是通过从矩阵或列表中删除指定的 Q 顶点来生成的。

  • 设置一个变量来跟踪连接组件的数量。

  • 最初迭代更新图中的每个顶点。

  • 对每个未探索的顶点应用图遍历算法(DFS 或 BFS)。

  • 标记遍历过程中访问过的顶点,以防止重新处理。

  • 继续遍历,直到与初始顶点相关的所有顶点都被看到。

  • 对于发现的每组唯一的互连顶点,将方程中的连通分量数量增加 1。

  • 要访问更新图中的每个顶点,请根据需要重复步骤 5 到 8。

  • 删除所需顶点后,图中断开的子图总数由连接组件计数的最终值表示。

示例

#include 
#include 
using namespace std;

void dfs(vector>& graph, vector& visited, int node) {
    visited[node] = true;
    for (int neighbor : graph[node]) {
        if (!visited[neighbor]) {
            dfs(graph, visited, neighbor);
        }
    }
}

int countReachableNodes(vector>& graph) {
    int N = graph.size();
    vector visited(N, false);
    int count = 0;

    for (int i = 0; i < N; ++i) {
        if (!visited[i]) {
            dfs(graph, visited, i);
            count++;
        }
    }

    return count;
}

int main() {
    // Create the graph (Adjacency List representation)
    vector> graph = {
        {1},
        {0, 2},
        {1},
        {4},
        {3}
    };

    int reachableNodes = countReachableNodes(graph);
    cout << "Number of nodes accessible from all other nodes: " << reachableNodes << endl;

    return 0;
}

输出

Number of nodes accessible from all other nodes: 2

结论

总之,网络分析和相关领域的一个关键指标是删除一定数量的顶点后图中剩余的连通分量的数量。基于矩阵的方法和 Kosaraju 算法都提供了计算此计数的有效方法。基于矩阵的方法在重新设计的图上使用 DFS 或 BFS 等图遍历算法来有效地查找链接组件,而 Kosaraju 算法在两次遍历中使用深度优先搜索来识别强连接组件。即使在删除某些顶点之后,这两种方法也会产生可靠的结果,有助于理解图的连通性和结构特征。图的属性和当前挑战的特定要求决定了要使用的方法。

热门AI工具

更多
DeepSeek
DeepSeek

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

豆包大模型
豆包大模型

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

通义千问
通义千问

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

腾讯元宝
腾讯元宝

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

文心一言
文心一言

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

讯飞写作
讯飞写作

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

即梦AI
即梦AI

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

ChatGPT
ChatGPT

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

相关专题

更多
堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

397

2023.07.18

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

575

2023.08.10

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

397

2023.07.18

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

575

2023.08.10

页面置换算法
页面置换算法

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

411

2023.08.14

java入门学习合集
java入门学习合集

本专题整合了java入门学习指南、初学者项目实战、入门到精通等等内容,阅读专题下面的文章了解更多详细学习方法。

1

2026.01.29

java配置环境变量教程合集
java配置环境变量教程合集

本专题整合了java配置环境变量设置、步骤、安装jdk、避免冲突等等相关内容,阅读专题下面的文章了解更多详细操作。

2

2026.01.29

java成品学习网站推荐大全
java成品学习网站推荐大全

本专题整合了java成品网站、在线成品网站源码、源码入口等等相关内容,阅读专题下面的文章了解更多详细推荐内容。

0

2026.01.29

Java字符串处理使用教程合集
Java字符串处理使用教程合集

本专题整合了Java字符串截取、处理、使用、实战等等教程内容,阅读专题下面的文章了解详细操作教程。

0

2026.01.29

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
消息队列MQ使用详解
消息队列MQ使用详解

共9课时 | 1.1万人学习

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

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