拓扑排序 用dfs或者bfs

拓扑排序是找DAG(有向无环图)的关键路径

拓扑排序从数据结构原理上说是不断找对应入度为0的点,找到就删去这个点和从此点出的边。这对应的其实是用bfs的方法,所以用bfs得到的其实除了判断还有每次找的出度为0的点(顺序不唯一),而dfs得到的是这个环的路径。(反正我一般都是并查集判断的。。)

先说bfs:

int in[N];
queue<int> qq;
void printfqq(){ // 输出拓扑序列,有环即无
	while(qq.size()){
		cout<<qq.front()<<" ";
		qq.pop();
	}
	cout<<endl;
}
int ans = -1;
void bfs_topsort(){
	queue<P> q;
	int sum=0;
	for(int i=1;i<=n;i++)
		if(in[i]==0)
		q.push(make_pair(i,1)),sum++;
	while(!q.empty()){
		P tmp = q.front();q.pop();
		int now=tmp.first;
		qq.push(now);
		for(int i=head[now];~i;i=nex[i]){
			int v = ver[i];
			in[v]--;
			if(in[v]==0){
				q.push(make_pair(v,tmp.second+1));
				ans = max(ans,tmp.second+1); // 最长链 
				sum++;
			}
		}
	}
	if(sum<n){
		cout<<"有环:"<<endl;
	}else cout<<"无环"<<endl; 
	printf("%d\n",ans);
	printfqq();//这是拓扑排序后的序列,不是关键路径 
}

dfs是对应遍历边,如果从当前点遍历到的点之前遍历过了,就有环,也就是找环路径:

int t,vis[N];
stack<int> st;
bool dfs(int x){
	vis[x]=-1;//正在遍历中 
	for(int i=head[x];~i;i=nex[i]){
		if(vis[ver[i]]==-1) return false;//存在环;
		else if(!vis[ver[i]] && !dfs(ver[i])) {st.push(ver[i]);return false; }	
	}
	vis[x]=1;//遍历结束 
	return true;
}
void dfs_topsort(){
	t=n;
	for(int i=1;i<=n;i++)
	if(!vis[i] && !dfs(i)){
		cout<<"有环:"<<endl;
		return; 
	}
	cout<<"无环"; 
}

下面贴测试代码:

#include<bits/stdc++.h>
using namespace std;
const int N = 500;
int ver[N],nex[N]; 
int n,m,cnt;
int head[N],in[N],tp[N];
stack<int> st;
queue<int> qq;
void add(int a,int b){
	ver[++cnt] = b;
	nex[cnt] = head[a];
	head[a] = cnt;
}
void init(){
	memset(head,-1,sizeof head);
	cin>>n>>m;
	for(int i=1;i<=m;i++){
		int a,b;scanf("%d %d",&a,&b);
		add(a,b);
		in[b]++;
	}
}
void printfst(){
			while(!st.empty()){
			cout<<st.top()<<" ";
			st.pop();
		}
		cout<<endl;
}
void printfqq(){
	while(qq.size()){
		cout<<qq.front()<<" ";
		qq.pop();
	}
	cout<<endl;
}
void bfs_topsort(){
	queue<int > q;
	int sum=0;
	for(int i=1;i<=n;i++)
		if(in[i]==0)
		q.push(i),sum++;
 
	int cnt=0;
	while(!q.empty()){
		int now=q.front();q.pop();
		tp[cnt++]=now;qq.push(now);
		for(int i=head[now];~i;i=nex[i]){
			in[ver[i]]--;
			if(in[ver[i]]==0){
				q.push(ver[i]);
				sum++;
			}
		}
	}
	if(sum<n){
		cout<<"有环:"<<endl;
	}else cout<<"无环"<<endl; 
	printfqq();
}
 
int t,vis[N];
bool dfs(int x){
	vis[x]=-1;//正在遍历中 
	for(int i=head[x];~i;i=nex[i]){
		if(vis[ver[i]]==-1) return false;//存在环;
		else if(!vis[ver[i]] && !dfs(ver[i])) {st.push(ver[i]);return false; }	
	}
	vis[x]=1;//遍历结束 
	return true;
}
void dfs_topsort(){
	t=n;
	for(int i=1;i<=n;i++)
	if(!vis[i] && !dfs(i)){
		cout<<"有环:"<<endl;
		return; 
	}
	cout<<"无环"; 
}
int main(){
	init();
	bfs_topsort();//1 对应第一个测试样例
	dfs_topsort();//2 3 4 
	printfst();
	return 0;
}

/*两组测试数据:
1)有环
4 4
1 2
2 3
3 4
4 2
2)无环
12 16
1 2
1 3
2 3
1 4
3 5
4 5
11 6
5 7
3 7
3 8
6 8
9 10
9 11
9 12
10 12
1 12*/

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,你的要求已经记录下来了。让我来解答你的问题。 在 gsearch.py 中实现 DFSBFS、基于 BFS 的最短路径和拓扑排序算法的方法如下: 1. DFS(深度优先搜索): DFS 通过深度优先的方式搜索图形结构。在图形结构中,DFS 沿着一个路径尽可能深入地搜索,直到找到目标节点为止,然后回溯到前一个节点,继续搜索其他路径。 以下是实现 DFS 算法的 Python 代码: ``` def dfs(graph, start, visited=None): if visited is None: visited = set() visited.add(start) for next in graph[start] - visited: dfs(graph, next, visited) return visited ``` 2. BFS(广度优先搜索): BFS 通过广度优先的方式搜索图形结构。在图形结构中,BFS 从起点开始,沿着所有的路径分别搜索一层,然后继续向下搜索下一层,直到找到目标节点为止。 以下是实现 BFS 算法的 Python 代码: ``` def bfs(graph, start): visited, queue = set(), [start] while queue: vertex = queue.pop(0) if vertex not in visited: visited.add(vertex) queue.extend(graph[vertex] - visited) return visited ``` 3. 基于 BFS 的最短路径算法: 基于 BFS 的最短路径算法可以用于在无权图中查找最短路径。算法从起点开始,通过 BFS 搜索图形结构,记录每个节点到起点的距离,并在找到目标节点时返回路径。 以下是实现基于 BFS 的最短路径算法的 Python 代码: ``` from collections import deque def shortest_path(graph, start, end): queue = deque([(start, [start])]) while queue: vertex, path = queue.popleft() for next in graph[vertex] - set(path): if next == end: return path + [next] else: queue.append((next, path + [next])) ``` 4. 拓扑排序算法: 拓扑排序算法用于有向无环图(DAG)中的节点排序。算法从 DAG 中选择一个没有前驱节点的节点,并将其输出。然后将该节点从 DAG 中删除,并更新其余节点的前驱节点。重复此过程,直到所有节点都被输出为止。 以下是实现拓扑排序算法的 Python 代码: ``` def topological_sort(graph): in_degree = {vertex: 0 for vertex in graph} for vertex in graph: for neighbor in graph[vertex]: in_degree[neighbor] += 1 queue = deque([vertex for vertex in in_degree if in_degree[vertex] == 0]) result = [] while queue: vertex = queue.popleft() result.append(vertex) for neighbor in graph[vertex]: in_degree[neighbor] -= 1 if in_degree[neighbor] == 0: queue.append(neighbor) return result ``` 希望这些代码可以帮助你实现 gsearch.py 中的算法。如果你有任何问题,请随时问我。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值