zoukankan      html  css  js  c++  java
  • 拓扑排序

          对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若边(u,v)∈E(G),则u在线性序列中出现在v之前。通常,这样的线性序列称为满足拓扑次序(Topological Order)的序列,简称拓扑序列。简单的说,由某个集合上的一个偏序得到该集合上的一个全序,这个操作称之为拓扑排序。

       拓扑排序可以通过DFS来实现。在排序某一个节点时,首先等到它的所有儿子节点排序完成后,再排序它本身。拓扑排序基于这样一个事实:若u到v存在通路,则u一定排在v的前面。如果图有环,则将不可能排出拓扑序列。

    /*UVa10305 - Ordering Tasks
    ---DFS进行拓扑排序
    --*/
    #define _CRT_SECURE_NO_DEPRECATE
    #include<iostream>
    #include<string.h>
    #include<vector>
    #include<algorithm>
    using namespace std;
    const int maxn = 100 + 5;
    
    vector<int>vec[maxn];  //邻接表
    int vis[maxn];
    int topo[maxn];
    int t;
    
    //默认顶点从0...n-1编号
    bool dfs(int u){
    	vis[u] = -1;  //等待排序
    	for (int i = 0; i < (int)vec[u].size(); i++){
    		int v = vec[u][i];
    		if (vis[v] < 0)return false;  //存在环,排序失败
    		else if (!vis[v] && !dfs(v))return false; //它的子节点排序失败
    	}
    	vis[u] =1; //标志当前节点排序完成
    	topo[--t] = u;  //加入排序列表中
    	return true;
    }
    bool toposort(int n){
    	t = n;
    	memset(vis, 0, sizeof(vis)); //初始态为未排序
    	for (int i = 0; i < n; i++)if (!vis[i])
    	      if (!dfs(i))return false;
    	return true;
    }
    int main(){
    	int m, n,u,v;
    	while (scanf("%d%d",&n, &m)&&n){
    		for (int i = 0; i < n; i++)vec[i].clear();
    		
    		for (int i = 0; i < m; i++){
    			scanf("%d%d", &u, &v);
    			u--; v--;
    			vec[u].push_back(v);
    		}
    		toposort(n);
    		printf("%d", topo[0]+1);
    		for (int i = 1; i < n; i++)
    			printf(" %d", topo[i]+1);
    		printf("
    ");
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    996工作制是奋斗还是剥削?
    动态链接的PLT与GOT
    The Product-Minded Software Engineer
    缓冲区溢出
    golang的加法比C快?
    C errno是否是线程安全的
    golang 三个点的用法
    GDB 单步调试汇编
    为什么CPU需要时钟这种概念?
    fliebeat配置手册
  • 原文地址:https://www.cnblogs.com/td15980891505/p/5829490.html
Copyright © 2011-2022 走看看