1.AOV与DAG

活动网络可以用来描述生产计划、施工过程、生产流程、程序流程等工程中各子工程的安排问题。

 
一般一个工程可以分成若干个子工程,这些子工程称为活动(Activity)。完成了这些活动,整个工程就完成了。例如下图的代表的计算机专业课程,学习就是一个工程,每门课程的学习就是整个工程中的一个活动。
 
我们可以用上图的有向图来表示课程之间的先修关系。在这种有向图中,顶点表示课程学习活动,有向边表示课程之间的先修关系。例如顶点C1到C8有一条有向边,表示课程C1必须在课程C8之前先学习完。
 
实际上,在这种有向图中,用顶点表示活动,用有向边表示活动u必须先于活动v进行。这种有向图叫做活动网络(Activity on Vertices),记做AOV网络。
 
前驱与后继:在AOV网络中,如果存在有向边,则称活动u必须在活动v之前进行,并称u是v的直接前驱,v是u的直接后继。如果存在有向路径,则称u是v的前驱,v是u的后继。
 
有向环与有向无环图:从前驱与后继的传递性和反自反性可以看出,AOV网络中不能出现有向回路(或称为有向环)。不含有向回路的有向图称为有向无环图(DAG, Directed Acyclic Graph)。
 
在AOV网络中如果出现了有向回路,则意味着某项活动以自己作为先决条件,这是不对的。
2.拓扑排序
 
判断有向无环图的方法是对AOV网络构造它的拓扑有序序列。即将各个顶点排列成一个线性有序的序列,使得AOV网络中所有存在的前驱和后继关系都能得到满足。
 
这种构造AOV网络全部顶点的拓扑有序序列的运算称为拓扑排序(Topological Sorting)。
 
如果通过拓扑排序能将AOV网络的所有顶点都排入一个拓扑有序的序列中,则该AOV网络中必定不存在有向环;相反,如果得不到所有顶点的拓扑有序序列,则说明该AOV网络中存在有向环,此AOV网络所代表的工程是不可行的。
 
例如对上图所示的学生选课工程图进行拓扑排序,得到的拓扑有序序列为:
 
C1,C2,C3,C4,C5,C6,C8,C9,C7
或者
C1,C8,C9,C2,C5,C3,C4,C7,C6 
 
由此可见,AOV网络的拓扑有序序列可能不唯一。
 
3.Kahn算法拓扑排序算法:

(1)从有向图中选择一个没有前驱(即入度为0)的顶点并且输出它;
(2)从网中删去该顶点,并且删去从该顶点发出的全部有向边;
(3)重复上述两步,直到剩余的网中不再存在没有前趋的顶点为止。
 
输入:
6 8
1 2
1 4
2 6
3 2
3 6
5 1
5 2
5 6
6 8
1 3
1 2
2 5
3 4
4 2
4 6
5 4
5 6
输出:
Great! There is not cycle.
5 1 4 3 2 6
Network has a cycle!
 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<sstream>
#include<functional>
using namespace std;
typedef long long ll;
const int maxn = + ;
const int INF = 1e9 + ;
int T, n, m, cases;
vector<int>Map[maxn];
int Count[maxn];
void topo()
{
stack<int>s;//存储入度数为0的顶点
vector<int>v;//存取拓扑排序的答案
for(int i = ; i <= n; i++)//下标从1开始
if(Count[i] == )s.push(i);
while(!s.empty())
{
int now = s.top();
v.push_back(now);
s.pop();
for(int j = ; j < Map[now].size(); j++)
{
if((--Count[Map[now][j]]) == )
{
s.push(Map[now][j]);
}
}
}
if(v.size() != n)cout<<"Network has a cycle!"<<endl;
else
{
cout<<"Great! There is not cycle."<<endl;
for(int i = ; i < v.size(); i++)cout<<v[i]<<" ";
cout<<endl;
}
}
int main()
{
while(cin >> n >> m)
{
if(!n && !m)break;
int u, v;
for(int i = ; i <= n; i++)Map[i].clear();
memset(Count, , sizeof(Count));
for(int i = ; i < m; i++)
{
cin >> u >> v;
Map[u].push_back(v);
Count[v]++;//存入度
}
topo();
}
return ;
}

时间复杂度:由于每个点入栈出栈一次,每条边扫描一次,时间复杂度为O(m + n)

 
 
 

AOV网络和Kahn算法拓扑排序的更多相关文章

  1. Java排序算法——拓扑排序

    package graph; import java.util.LinkedList; import java.util.Queue; import thinkinjava.net.mindview. ...

  2. 2017 ACM-ICPC(乌鲁木齐赛区)网络赛 H.Skiing 拓扑排序+最长路

    H.Skiing In this winter holiday, Bob has a plan for skiing at the mountain resort. This ski resort h ...

  3. 基于DFS的拓扑排序

    传送门:Kahn算法拓扑排序 摘录一段维基百科上的伪码: L ← Empty list that will contain the sorted nodes S ← Set of all nodes ...

  4. 算法-图(3)用顶点表示活动的网络(AOV网络)Activity On Vertex NetWork

    对于给定的AOV网络,必须先判断是否存在有向环. 检测有向环是对AOV网络构造它的拓扑有序序列,即将各个顶点排列成一个线性有序的序列,使得AOV网络中所有直接前驱和直接后继关系都能得到满足. 这种构造 ...

  5. 【数据结构与算法Python版学习笔记】图——拓扑排序 Topological Sort

    概念 很多问题都可转化为图, 利用图算法解决 例如早餐吃薄煎饼的过程 制作松饼的难点在于知道先做哪一步.从图7-18可知,可以首先加热平底锅或者混合原材料.我们借助拓扑排序这种图算法来确定制作松饼的步 ...

  6. 拓扑排序 (Topological Sorting)

    拓扑排序(Topological Sorting) 一.拓扑排序 含义 构造AOV网络全部顶点的拓扑有序序列的运算称为拓扑排序(Topological Sorting). 在图论中,拓扑排序(Topo ...

  7. python拓扑排序

    发现自己并没有真的理解拓扑排序和多重继承,再次学习了下 拓扑排序要满足如下两个条件 每个顶点出现且只出现一次. 若A在序列中排在B的前面,则在图中不存在从B到A的路径. 拓扑排序算法 任何无回路的顶点 ...

  8. nyoj349 poj1094 Sorting It All Out(拓扑排序)

    nyoj349   http://acm.nyist.net/JudgeOnline/problem.php?pid=349poj1094   http://poj.org/problem?id=10 ...

  9. POJ1094 拓扑排序

    问题:POJ1094   本题考查拓扑排序算法   拓扑排序:   1)找到入度为0的点,加入已排序列表末尾: 2)删除该点,更新入度数组.   循环1)2)直到 1. 所有点都被删除,则找到一个拓扑 ...

随机推荐

  1. ACM搜索问题盘点

    深度搜索:棋盘问题,详见http://poj.org/problem?id=1321 //#include<bits/stdc++.h> #include<cstdio> #i ...

  2. 打印二叉堆(Java实现)

    打印二叉堆:利用层级关系 我这里是先将堆排序,然后在sort里执行了打印堆的方法printAsTree() public class MaxHeap<T extends Comparable&l ...

  3. 用disabled属性修饰a标签,a标签仍然能点击

    1.不知道各位同学有没有遇到跟我相同的问题,就是用jQuery操作a标签disabled的,来控制重复提交表单 做过开发的都知道,表单验证重复提交,包含前端和后端,两方面的控制.前端控制使我们常用的手 ...

  4. CentOS7.2下Nginx的使用

    Nginx的启动 指定配置文件的方式启动 nginx -c /etc/nginx/nginx.conf 对于yum安装的nginx,使用systemctl命令启动 systemctl start ng ...

  5. Java使用对象流读取文件的问题

    把对象进行持久化(把对象存到本地)要用到对象流进行处理,在用对象流处理过程中,在写对象和读对象时候遇到了很多问题,分享一下. 我们处理对象数据的时候不可能只处理一个对象,在系统运行的时候,可能产生的对 ...

  6. AsyncTask源码笔记

    AsyncTask源码笔记 AsyncTask在注释中建议只用来做短时间的异步操作,也就是只有几秒的操作:如果是长时间的操作,建议还是使用java.util.concurrent包中的工具类,例如Ex ...

  7. java基础学习系列三

    产生随机数 例如 [a,b] Math.random*(b-a+1)+a 公式推算 [3,55]-----[0,52]+3 *53+3

  8. Redis学习笔记(三)常用命令整理

    Redis 常用命令 1.DEL key 删除key2.EXISTS key 检查key是否存在3.KEYS * 查看所有的key4.EXPIRE key seconds 设置key的过期时间5.TT ...

  9. 自动化运维工具---expec

    作为运维经常操作Linux服务器是不可避免的事情的,那么你们都是怎么管理的呢? 我们管理的方式较为复杂了,我说一下: 有一套服务器资产管理系统,所有服务器都记录在上面,包括用户名密码,内外网地址都会有 ...

  10. C第九次博客作业--指针

    一.PTA实验作业 题目1:两个4位正整数的后两位互换 1. 本题PTA提交列 2. 设计思路 3.代码截图 本题调试过程碰到问题及PTA提交列表情况说明 刚开始想到的交换是令t=a;a=b;b=t这 ...