首页 > 其他分享 >连通性问题(有向图)(未完结)

连通性问题(有向图)(未完结)

时间:2024-09-13 09:26:43浏览次数:8  
标签:cnt 有向图 连通性 未完结 int ist ++ dfn low

强连通分量

我们首先定义两种边:返祖边为从一个点指向其祖先的边;横叉边从某个点指向树中另一个子树中的点的边。两者统称为非树边。而剩下的边即为树边,树边也就是在 \(dfs\) 树上的边。

我们定义 \(dfn_i\) 为 \(i\) 是第几个被 \(dfs\) 到的,\(low_i\) 从 \(i\) 出发走任意条边,但是最后一条边必须是返祖边的情况下能够到达的点的 \(dfn\) 的最小值。

于是我们便有了求出 \(dfn\) 和 \(low\) 的代码:

void tar(int u){
	low[u]=dfn[u]=++tot;
	stk[++top]=u;
	ist[u]=1;
	for(int i=h[u];~i;i=ne[i]){
		int j=e[i];
		if(!dfn[j]){
			tar(j);
			low[u]=min(low[u],low[j]);
		}
		else if(ist[j]){
			low[u]=min(low[u],dfn[j]);
		}
	}
}

接着我们考虑怎么通过 \(low\) 和 \(dfn\) 求出强连通分量。

我们假设现在遇到了一个点 \(x\),并且 \(dfn_x=low_x\)。这说明从 \(x\) 出发按照之前的要求能走到的 \(dfn\) 最小的点是他自己。

换句话说,\(x\) 是其所在强连通分量的最上面的点。

于是我们不断弹出栈,直到弹出了 \(x\)(不难证明 \(x\) 在栈中),弹出的这些点与 \(x\) 同属一个强连通分量,于是就做完了。

完整代码:

#include<bits/stdc++.h>
#define int long long
#define N 10005
#define M 100005
using namespace std;
int n,m,h[N],e[M],ne[M],idx,cnt,tot;
int stk[N],col[N],dfn[N],low[N],top;
bool ist[N],st[N];
vector<int>res[N];
void add(int a,int b){
	e[idx]=b;ne[idx]=h[a];h[a]=idx++;
}
void tar(int u){
	low[u]=dfn[u]=++tot;
	stk[++top]=u;
	ist[u]=1;
	for(int i=h[u];~i;i=ne[i]){
		int j=e[i];
		if(!dfn[j]){
			tar(j);
			low[u]=min(low[u],low[j]);
		}
		else if(ist[j]){
			low[u]=min(low[u],dfn[j]);
		}
	}
	if(dfn[u]==low[u]){
		cnt++;
		int y;
		do{
			y=stk[top--];
			ist[y]=0;
			col[y]=cnt;
			res[cnt].push_back(y);
		}while(y!=u);
	}
}
signed main(){
	cin>>n>>m;
	memset(h,-1,sizeof h);
	for(int i=1;i<=m;i++){
		int a,b;
		cin>>a>>b;
		add(a,b);
	}
	for(int i=1;i<=n;i++){
		if(!dfn[i]){
			tar(i);
		}
	}
	cout<<cnt<<'\n';
	for(int i=1;i<=n;i++){
		if(!st[col[i]]){
			sort(res[col[i]].begin(),res[col[i]].end());
			for(auto it:res[col[i]]){
				cout<<it<<' ';
			}
			cout<<'\n';
			st[col[i]]=1;
		}
	}
	return 0;
}

标签:cnt,有向图,连通性,未完结,int,ist,++,dfn,low
From: https://www.cnblogs.com/zxh923aoao/p/18411566

相关文章

  • 代码随想录训练营 Day53打卡 图论part04 110. 字符串接龙 105. 有向图的完全可达性 10
    代码随想录训练营Day53打卡图论part04一、卡码110.字符串接龙本题与力扣127题是一样的,所以这里使用力扣127题。字典wordList中从单词beginWord到endWord的转换序列是一个按下述规格形成的序列beginWord->s1->s2->…->sk:    每一对相邻的单词只......
  • 图论篇--代码随想录算法训练营第五十三天打卡| 110. 字符串接龙,105.有向图的完全可达
    110.字符串接龙题目链接:110.字符串接龙题目描述:字典strList中从字符串beginStr和endStr的转换序列是一个按下述规格形成的序列: 序列中第一个字符串是beginStr。序列中最后一个字符串是endStr。 每次转换只能改变一个字符。 转换过程中的中间字符串必须是字典......
  • WGCLOUD使用指南 - 监测数据库的连通性
    数据可视化监测是WGCLOUD的一个重要模块,可以帮我们监控数据源是否在线,自定义sql查询数据进行可视化展示,比如新增订单、注册用户量、数据库运行参数等信息数据监控是由server来监测的,因此要保证server主机能够访问到数据库如果server无法访问被监控的数据源,怎么监控 1、......
  • 信息学奥赛初赛天天练-84-NOIP2014普及组-基础题3-总线、存储器、邮件协议、二叉树、
    信息学奥赛初赛天天练-84-NOIP2014普及组-基础题3-总线、存储器、邮件协议、二叉树、满二叉树、顶点的度、无向图、有向图PDF文档公众号回复关键字:202409061NOIP2014普及组基础题36CPU、存储器、I/O设备是通过()连接起来的A接口B总线C控制线D系统文......
  • 有向图最短路径与BFS算法的研究
    有向图最短路径与BFS算法的研究引言有向图G=(V,E)的定义与例子BFS算法及其局限性特定边集E'的构造确认最短路径实现BFS并验证结果(C代码)引言在图论中,寻找最短路径是一个经典问题。广度优先搜索(BFS)是一种在无权重图(即所有边的权重相同)中找到从源节点到所有其他......
  • 有向图的最短路径与BFS算法的局限性分析
    有向图的最短路径与BFS算法的局限性分析引言有向图G=(V,E)的示例图G的邻接表表示问题描述BFS算法回顾BFS在示例图G中的应用及局限性构造E_s并证明BFS的局限性C语言实现及验证分析C语言实现的BFS算法结论引言在图论中,最短路径问题是寻找从一个结点(源结点)到......
  • 图论连通性相关
    并查集普通并查集:路径压缩写法:structUnion_Find_Set{ intf[N]; inlinevoidinit(){ for(inti=1;i<=n;++i) f[i]=i; } inlineintfind(intx){ if(x!=f[x])f[x]=find(f[x]); returnf[x]; } inlinevoidmerge(inta,intb){ intx......
  • C++ 有向图拓扑排序算法
    代码 #include<algorithm>#include<cassert>#include<functional>#include<map>#include<memory>#include<queue>#include<set>#include<unordered_set>#include<vector>namespacejc{templa......
  • 代码随想录 day 54 字符串接龙 | 有向图的完全可达性 | 岛屿的周长
    字符串接龙字符串接龙解题思路利用每次更改一次的特性在字典中来找到符合条件的字符串,同时,我们利用set数据结构来筛选该字符串是否被访问过,同时记录到达该字符串所需要的路径长度知识点心得有向图的完全可达性有向图的完全可达性解题思路有向图和无向图的区别在于它的边......
  • #java学习笔记(面向对象)----(未完结)
    一基础相关知识点:1.一个对象的调用首先我们创建一个Phone类publicclassPhone{//成员变量Stringname;intage;Stringfavourite;//成员方法publicvoidmyName(){System.out.println(name);}publicvoidmyAge(){......