图的连通性问题专题整理

图的连通性问题专题整理

大家好,又见面了,我是全栈君,祝每个程序员都可以多学几门语言。

   这一篇博客继续以一些OJ上的题目为载体,对图的连通性专题进行整理一下。会陆续的更新。。。


爱上大声地

一、相关定义

1、假设图G中随意两点能够相互到达。则称图G为强连通图。

2、假设图G不是强连通图,而它的子图G’是强连通图。那么称图G’为图G的强连通分量


求强连通分量主要下面三种算法:Kosaraju算法、Tarjan算法、Garbow算法。。。


二、例题

1、HDU 1269

1)使用Tarjan算法来解决

/*
 * HDU_1269_2.cpp
 *
 *  Created on: 2014年7月7日
 *      Author: pc
 */

#include <iostream>
#include <cstdio>


using namespace std;


const int maxm = 100010;//边的最大数目
const int maxn = 10005;//顶点的最大值

/**
 * 链式前向星
 */
struct node{
	int e;
	int next;
}edge[maxm];


int head[maxn];

int n,m,k;
int low[maxn];//low[v]用与保存节点v邻接的未删除的节点u的low[u]和low[v]中的最小值
int dfn[maxn];//dfn[i]用来表示节点i的訪问时间
int stack[maxn];//
int vis[maxn];//vis[i] = 1..表示节点i已经被訪问过
int cnt,index,top;//cnt: 强连通分量的个数.top:用来维护栈中的数据


/**
 * 加入�一条边的操作。。。
 * s: 边的起点
 * e: 边的终点
 */
void add(int s,int e){
	edge[k].e = e;
	edge[k].next = head[s];
	head[s] = k++;
}

/**
 * 使用tarjan算法来求强连通分量的个数
 * s: 表示要訪问的节点
 */
void tarjan(int s){
	//现骨干变量的初始化
	low[s] = dfn[s] = ++index;
	stack[++top] = s;
	vis[s] = true;


	//訪问节点s邻接的全部未删除节点e
	int i;
	for(i = head[s] ; i != -1 ; i = edge[i].next){
		int e = edge[i].e;

		if(!dfn[e]){
			tarjan(e);
			low[s] = min(low[s],low[e]);
		}else if(vis[e]){
			low[s] = min(low[s],dfn[e]);
		}
	}

	if(low[s] == dfn[s]){//表示当前节点就是一个强连通分量的根
		cnt++;

		int e;
		do{
			e = stack[top--];
			vis[e] = false;
		}while(s != e);
	}
}


/**
 * 完毕初始化的相关操作..
 */
void init(){
	memset(head,-1,sizeof(head));
	memset(dfn,0,sizeof(dfn));//素有节点被訪问的时间戳被初始化为0.表示还没有被訪问
	memset(vis,0,sizeof(vis));//一開始全部的节点被标记为未訪问过...

	cnt = 0;//cnt: 强连通分量的个数..
	index = 0;
	k = 0;//边的条数
	top = -1;// 用来维护栈中的元素
}

int main(){
	while(scanf("%d%d",&n,&m),n||m){
		init();

		int i;
		for(i = 0 ; i < m ; ++i){
			int a,b;
			scanf("%d%d",&a,&b);

			add(a,b);
		}


		for(i = 1 ; i <= n ; ++i){
			if(!dfn[i]){
				tarjan(i);
			}
		}

		if(cnt == 1){
			printf("Yes\n");
		}else{
			printf("No\n");
		}
	}

	return 0;
}








版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/118258.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • vs2010注册密钥_vs2012ultimate密钥

    vs2010注册密钥_vs2012ultimate密钥MicrosoftVisualStudioUltimate2012旗舰版有效注册密钥:YKCW6-BPFPF-BT8C9-7DCTH-QXGWC

    2022年10月14日
    1
  • 表空间

    表空间

    2022年2月1日
    39
  • 通用高级模组修改器(魔兽世界改模型插件)

    准备工作:所需软件WINHEX,百度一下就有,华军什么的也可以。还有就是反向十六进制代码转换器。另外还需要一个代码查询网站http://wow.allakhazam.com/。打开网站点“search”。然后将语言选择为中文,输入要查询的装备的名称查询。然后点所需装备的连接,在出现的网页中点XML。拖动网页,会看见一片数字,其他的不管,只需要2个displayinfo中间的数字,例如,逐风剑的就是…

    2022年4月16日
    636
  • ureport2报表详细使用(一)-集成及配置

    ureport2报表详细使用(一)-集成及配置一 报表简介 UReport2 是一款基于架构在 Spring 之上纯 Java 的高性能报表引擎 通过迭代单元格可以实现任意复杂的中国式报表 在 UReport2 中 提供了全新的基于网页的报表设计器 可以在 Chrome Firefox 等各种主流浏览器运行 不支持 IE 使用 UReport2 打开浏览器即可完成各种复杂报表的设计制作 二 主体功能 UReport2 支持创建数据源 添加数据集 并对数据集进行函数 表达式处理 参考 数据处理 UReport2 支持对数据集形成可视化报表 包

    2025年10月13日
    3
  • CMD命令:不是内部或者外部命令也不是可运行的程序或批处理文件

    CMD命令:不是内部或者外部命令也不是可运行的程序或批处理文件前言:相信有很多小伙伴都比较喜欢使用Command命令来快速的打开或运行程序,但是有些时候命令提示符会和我们开个小玩笑。今天我就教大家如何管教这个不听话的cmd!场景:看有些大神在命令提示符里输入两句命令就能执行一大串东西,本着学习的态度,先试试再说!没成想出现了:“不是内部或外部命令,也不是可运行的程序或批处理文件。”通过各种查各种找,终于…

    2022年5月8日
    391
  • WiFi的2.4G、5G、6G频段「建议收藏」

    WiFi的2.4G、5G、6G频段「建议收藏」目前WiFi已经推出了6G频段,Android源码中也增加了相关的功能,这里总结一下。2.4G一共分为14个信道(1-14),从2412到2484,每个信道的有效宽度是20MHz,另外还有2MHz的强制隔离频带(类似于公路上的隔离带)。即,对于中心频率为2412MHz的1信道,其频率范围为2401~2423MHz。5G一共有60个信道(32-173),从5160到5865,在中国支持的5G信道为363840444648525456606264,后六个是DFS。6G为1-2

    2022年10月20日
    4

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号