Connectivity in a directed graph

Given a directed graph, find out whether the graph is strongly connected or not. A directed graph is strongly connected if  there is a path between any two pair of vertices. For example, following is a strongly connected graph.

It is easy for undirected graph, we can just do a BFS and DFS starting from any vertex. If BFS or DFS visits all vertices, then 
the given undirected graph is connected. This approach won’t work for a directed graph. For example, consider the 
following graph which is not strongly connected. If we start DFS (or BFS) from vertex 0, we can reach all vertices, but if we 
start from any other vertex, we cannot reach all vertices.

How to do for directed graph?
A simple idea is to use a all pair shortest path algorithm like Floyd Warshall or find Transitive Closure of graph. Time 
complexity of this method would be O(v3).
We can also do DFS V times starting from every vertex. If any DFS, doesn’t visit all vertices, then graph is not strongly 
connected. This algorithm takes O(V*(V+E)) time which can be same as transitive closure for a dense graph.
A better idea can be Strongly Connected Components (SCC) algorithm. We can find all SCCs in O(V+E) time. If number of 
SCCs is one, then graph is strongly connected. The algorithm for SCC does extra work as it finds all SCCs.

Following is a simple DFS based algorithm that does two DFS traversals of graph:
1) Initialize all vertices as not visited.
2) Do a DFS traversal of graph starting from any arbitrary vertex v. If DFS traversal doesn’t visit all vertices, then return 
false.
3) Reverse all arcs (or find transpose or reverse of graph)
4) Mark all vertices as not-visited in reversed graph.
5) Do a DFS traversal of reversed graph starting from same vertex v (Same as step 2). If DFS traversal doesn’t visit all 
vertices, then return false. Otherwise return true.

The idea is, if every node can be reached from a vertex v, and every node can reach v, then the graph is strongly 
connected. In step 2, we check if all vertices are reachable from v. In step 4, we check if all vertices can reach v (In reversed 

graph, if all vertices are reachable from v, then all vertices can reach v in original graph).


#include<iostream>
#include<list>
using namespace std;

class Graph {
	int vexNum;
	list<int>* adjacents;
public:
	Graph(int _vexNum);
	~Graph();
	void addEdge(int v, int w);
	void DFSUtil(int v, bool* visited);
	bool isStrongConnected();
};

Graph::Graph(int _vexNum) {
	vexNum = _vexNum;
	adjacents = new list<int>[vexNum];
}

Graph::~Graph() {
	delete []adjacents;
}

void Graph::addEdge(int v, int w) {
	adjacents[v].push_back(w);
}

void Graph::DFSUtil(int v, bool* visited) {
	visited[v] = true;
	list<int>::iterator iter;
	for (iter = adjacents[v].begin(); iter != adjacents[v].end(); iter++)
		if (false == visited[*iter])
			DFSUtil(*iter, visited);
}

bool Graph::isStrongConnected() {
	bool* visited = new bool[vexNum];
	int v;
	for (v = 0; v < vexNum; v++)
		visited[v] = false;
	DFSUtil(0, visited);
	for (v = 0; v < vexNum; v++)
		if (false == visited[v]) {
			delete []visited;
			return false;
		}
	Graph gt = Graph(vexNum);
	list<int>::iterator iter;
	for (v = 0; v < vexNum; v++) {
		for (iter = adjacents[v].begin(); iter != adjacents[v].end(); iter++)
			gt.adjacents[*iter].push_back(v);
	}
	for (v = 0; v < vexNum; v++)
		visited[v] = false;
	gt.DFSUtil(0, visited);
	for (v = 0; v < vexNum; v++)
		if (false == visited[v]) {
			delete []visited;
			return false;
		}
	delete []visited;
	return true;
}

int main(int argc, char* argv[]) {
	Graph g1 = Graph(5);
    g1.addEdge(0, 1);
    g1.addEdge(1, 2);
    g1.addEdge(2, 3);
    g1.addEdge(3, 0);
    g1.addEdge(2, 4);
    g1.addEdge(4, 2);
	if (g1.isStrongConnected())
		cout << "yes" << endl;
	else
		cout << "non" << endl;
	Graph g2(4);
    g2.addEdge(0, 1);
    g2.addEdge(1, 2);
    g2.addEdge(2, 3);
	if (g2.isStrongConnected())
		cout << "yes" << endl;
	else
		cout << "non" << endl;
	cin.get();
	return 0;
}


# 导入需要的模块 import numpy as np import open3d as o3d # 用于读写pcd文件 from sklearn.neighbors import kneighbors_graph # 用于构建KNN图 from scipy.sparse.csgraph import connected_components # 用于找到连通域 # 读取点云数据 pc = o3d.io.read_point_cloud(r'E:\BISHE\pcd\neuvsnap_0418_154523.pcd') # 读取pcd文件 points = np.asarray(pc.points) # 转换为numpy数组 # 构建KNN图,k为邻居数,可以根据数据密度调整 k = 10 graph = kneighbors_graph(points, k, mode='connectivity', include_self=False) # 找到最大的连通域 n_components, labels = connected_components(graph, directed=False) largest_label = np.argmax(np.bincount(labels)) # 找到点数最多的标签 largest_component = points[labels == largest_label] # 筛选出对应的点 # 保存筛选后的点云数据为pcd文件 pc_filtered = o3d.geometry.PointCloud() # 创建新的点云对象 pc_filtered.points = o3d.utility.Vector3dVector(largest_component) # 设置点云数据 o3d.io.write_point_cloud(r'E:\BISHE\pcd\output1.pcd', pc_filtered) # 保存为pcd文件 # 为点云数据设置颜色 colors = np.zeros((points.shape[0], 3)) # 创建一个颜色数组,大小和点云数组一致 colors[labels == largest_label] = [0.5, 0.5, 0.5] # 将保留的点云设置为灰色 colors[labels != largest_label] = [1.0, 0.0, 0.0] # 将处理的点云设置为红色 pc.colors = o3d.utility.Vector3dVector(colors) # 将颜色数组赋值给点云对象 # 可视化点云数据 o3d.visualization.draw_geometries([pc]) # 调用open3d的可视化函数,显示点云对象这段代码降噪原理是什么
05-23
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值