zoukankan      html  css  js  c++  java
  • Topological Sort

    拓扑排序将有向无环图的所有顶点排成一个线性序列,使得其中任意两个顶点(u、v),若存在有向边(u->v),那么在线性序列中(u)必然在(v)之前。

    思想:

    1. 将所有入度为0的顶点入队;
    2. 取队首结点输出,删除所有从该结点出发的边,并将这些边到达的顶点的入度减1,若某顶点入度减为0,将其入队;
    3. 重复2,直到队列为空。若进过队的结点数为(n),排序成功,否则图中有环
    /*复杂度O(V+E)*/
    int vertexNum;
    vector<int> adjList[MAXV];  //邻接表 
    int inDegree[MAXV];    //顶点入度,读入时记录
    
    bool topologicalSort()
    {
    	int cnt = 0;
    	queue<int> q;   //若有多个入度为0的顶点要选择编号最小的,可使用priority_queue
    	
    	//将所有入度为0的顶点入队 
    	for(int i = 0;i < vertexNum;i++)
    	{
    		if(inDegree[i] == 0)
    		q.push(i);
    	}
    	
    	while(!q.empty())
    	{
    		int front = q.front();
    		cout << front << endl;  //输出拓扑序列
    		q.pop();
    		
    		for(int i = 0;i < adjList[front].size();i++)
    		{
    			int v = adjList[front][i];  //front的后继结点
    			inDegree[v]--;
    			if(indegree[v] == 0)
    				q.push(v); 
    		}
    		adjList[front].clear();   //删掉从该顶点出发的所有边
    		cnt++;
    	}
    	
    	if(cnt == vertexNum)
    		return true;
    	else
    		return false;
    } 
    
    // dfs version, reverse ans is the topological sequence
    enum states {UNKNOWN, VISITING, VISITED};
    bool hasCycle(vector<vector<int>>& graph, int cur, vector<int>& state, vector<int>& ans) {
    	if (state[cur] == VISITING) return true;
    	if (state[cur] == VISITED) return false;
    
    	state[cur] = VISITING;
    	for (auto neighbors : graph[cur]) {
    		if (hasCycle(graph, neighbors, state, ans))
    			return true;
    	}
    	state[cur] = VISITED;
    	ans.push_back(cur);
    
    	return false;
    }
    
  • 相关阅读:
    整除
    奇怪的生日礼物
    欧拉函数平方和
    奇怪的生日礼物(数论基础)
    整除(简单数论)
    Tarjan求割点
    构造双连通(tarjan)
    次小生成树
    机器扫边
    最短路径(树形DP)
  • 原文地址:https://www.cnblogs.com/EIMadrigal/p/11615114.html
Copyright © 2011-2022 走看看