首页 > 其他分享 >kosarajo求强连通分量

kosarajo求强连通分量

时间:2023-02-01 23:24:45浏览次数:59  
标签:连通 gr vis kosarajo int include 求强

kosarajo求强连通分量的证明

  • 因为根据反向图的dfs求出的拓扑序列使得原本的dag图中点的搜索优先级倒转
  • 所以在原图dfs会优先将最末端的点优先跑完,而上面的点再跑时,因为下面的点已经被标记过,阻止了连通块的扩张,所以是正确的

例题

poj2186

题目链接

题意

  • n个点m条边,求有多少个点是任意点均可达到的

思路

  • 根据反向图求出拓扑序列,再使用正向dfs求出连通分量,题目所求即第一个强连通分量中点的个数
  • 注意:图本身可能是非联通的,要特判

代码

#include <iostream>
#include <cstring>
#include <string>
#include <vector>
#include <set>
#include <algorithm>
using namespace std;
const int N = 10005;
vector<int> g[N], gr[N], path;
int vis[N], sscid[N], n, m;
void dfs1(int x) {
	vis[x] = 1;
	for(unsigned int i = 0; i < gr[x].size(); ++ i) {
		int y = gr[x][i];
		if(!vis[y]) {
			dfs1(y);
		}
	}
	path.push_back(x);
	return;
}
void dfs2(int x, int cnt) {
	sscid[x] = cnt;
	for(unsigned int i = 0; i < g[x].size(); ++ i) {
		int y = g[x][i];
		if(!sscid[y]) {
			dfs2(y, cnt);
		}
	}
	return;
}
void dfs3(int x) {
	vis[x] = 1;
	for(unsigned int i = 0; i < gr[x].size(); ++ i) {
		int y = gr[x][i];
		if(!vis[y]) {
			dfs3(y);
		}
	}
}
void kosarajo() {
	int cnt = 0;
	for(int i = 1; i <= n; ++ i) {
		if(!vis[i]) {
			dfs1(i);
		}
	}
	reverse(path.begin(), path.end());
	for(unsigned int i = 0; i < path.size(); ++ i) {
		int x = path[i];
		if(!sscid[x]) {
			dfs2(x, ++ cnt);
		}
	}
}
void init() {
	for(int i = 0; i < N; ++ i) {
		g[i].clear();
		gr[i].clear();
	}
	memset(vis, 0, sizeof(vis));
	memset(sscid, 0, sizeof(sscid));
	return;
}
int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	cin >> n >> m;
	init();
	for(int i = 1; i <= m; ++ i) {
		int u, v;
		cin >> u >> v;
		g[u].push_back(v);
		gr[v].push_back(u);
	}
	kosarajo();
	int count = 0, x = 0;
	for(int i = 1; i <= n; ++ i) {
		if(sscid[i] == 1) {
			++ count;
			x = i;
		}
	}
	memset(vis, 0, sizeof(vis));
	dfs3(x);
	bool flag = true;
	for(int i = 1; i <= n; ++ i) {
		if(!vis[i]) {
			flag = false;
			break;
		}
	}
	if(!flag) cout << 0 << "\n";
	else cout << count << "\n";
	return 0;
}

标签:连通,gr,vis,kosarajo,int,include,求强
From: https://www.cnblogs.com/lemonsbiscuit/p/17084472.html

相关文章

  • Tarjan 强连通分量 板子
    #include<bits/stdc++.h>usingnamespacestd;constintN=10005;intn,m;intscc[N],siz[N],cnt;intdfn[N],low[N],tot;bitset<N>instk;stack<int>stk;......
  • Tarjan 算法 (图连通性)
    1.割边和割点首先我们dfs一遍构造出dfs树并排出dfn序.显然这棵树没有横叉边.考虑割边的形成条件.显然割边只能是树边,因为非树边会和对应的树上的路径组成环.......
  • 图的连通性问题
    \(dfs\)树及其他概念在这样一棵由在图上进行\(dfs\)所形成的\(dfs\)树中,我们注明了三种边。黑色的边为树边。绿色的边为前向边,由一个节点指向它子树上的节点。......
  • 畅捷通T+与道一云对接集成报销信息列表连通凭证创建
    畅捷通T+与道一云对接集成获取报销信息列表连通凭证创建数据源系统:道一云在道一云坚实的技术基础上,道一云推出全新升级的2.0产品矩阵,分别是低码平台、智能门户、场景......
  • 伯俊ERP与金蝶云星空对接集成连通应收单新增
    伯俊ERP与金蝶云星空对接集成表头表体组合查询连通应收单新增(应收单-标准应收单(KD应收单销售退)数据源系统:伯俊ERP未来,伯俊科技也会砥砺前行,不断为品牌提供更全面的零售终......
  • Linux下检测网卡与网线连通状态
    Linux_stat.c#include<stdio.h>#include<stdlib.h>#include<string.h>#include<fcntl.h>#include<errno.h>#include<sys/ioctl.h>#include<sys/types.h>#include<sy......
  • 外网测试连通率tcping
    tcping10.10.10.108081   二、tcping介绍tcping:tcping命令基于tcp协议监控,可以从较低级别的协议获得简单的,可能不可靠的数据报服务。原则上,TCP应该能够在从容硬......
  • 一次代码重构 JavaScript 图连通性判定
    简介说重构其实就是整理了代码,第一次自己手写写的很丑,然后看了书上写的,虽然和书上的思路不同但是整理后几乎一样漂亮效果整体代码如下classNode{AdjNodes=new......
  • 求解连通图问题的常用方法
    判断图是否连通以及连通子图个数的问题一般常见的解法是并查集或者图的遍历(dfs/bfs)连通图经典并查集写法#include<bits/stdc++.h>usingnamespacestd;constintN......
  • Count Connected Components(判断连通块数量)
    题目描述:Youaregivenasimpleundirectedgraphwith\(N\)verticesnumbered\(1\)to\(N\)and\(M\)edgesnumbered\(1\)to\(M\).Edge\(i\)connectsverte......