body, table{font-family: 微软雅黑; font-size: 13.5pt}
table{border-collapse: collapse; border: solid gray; border-width: 2px 0 2px 0;}
th{border: 1px solid gray; padding: 4px; background-color: #DDD;}
td{border: 1px solid gray; padding: 4px;}
tr:nth-child(2n){background-color: #f8f8f8;}

AOV网(Ativity On Vertex Network):
  在一个表示工程的有向图中,用顶点表示活动,用弧表示活动之间的优先关系,这样的有向图为顶点表示活动的网——AOV。

拓扑序列:
  设 G = (V,E) 是一个具有n个顶点的有向图,V中的顶点序列V1,V2,……,Vn,满足若从顶点Vi到Vj有一条路径,则在顶点序列中顶点Vi必须在Vj之前。这样的一个顶点序列叫做拓扑序列。

拓扑排序:
  对一个有向图构造拓扑序列的过程。构造过程中如果网的顶点全部输出,表示不存在环(回路)的AOV网;否则不是AOV网。

拓扑排序算法:

AOV:3 → 1 → 2 → 6 → 0 → 4 → 5 → 8 → 7 → 12 → 9 → 10 → 13 → 11

/* AOV.h */

#ifndef __AOV_H__
#define __AOV_H__
#include<iostream>
#include"Graph.h"
namespace meihao
{
        //边表结点
        typedef struct EdgeNode
        {
                int vertexIdx;  //邻接点域,存放该结点在顶点表数组中的下标
                struct EdgeNode* next;  //存放下一个边表结点的位置
        }edgeNode,*pEdgeNode;
        //顶点表结点
        typedef struct VertexNode
        {
                int in;  //顶点入度
                int data;  //顶点与,存放顶点数据信息
                edgeNode* firstEdge;
        }vertexNode,*pVertexNode;
        void initDataStruct(const meihao::Graph& g,vertexNode*& vertexArr);  //根据图来初始化出我们要的顶点数组和对应的边表
        int TopologicalSort_AOV(const meihao::Graph& g);  //成功返回0,失败返回-1
};
#endif



/* testmain.cpp */
#include"AOV.h"
#include"Graph.h"
#include<iostream>
using namespace std;
int main()
{
        meihao::Graph g("data.txt");
        int ret = meihao::TopologicalSort_AOV(g);
        if(0==ret)
                cout<<"success!"<<endl;
        else
                cout<<"fail!"<<endl;
        system("pause");
}

/* AOV.cpp */

#include"AOV.h"
#include<stack>
namespace meihao
{
        void initDataStruct(const meihao::Graph& g,vertexNode*& vertexArr)
        {
                int vertexNum = g.getGraphVertexNumber();
                vertexArr = new vertexNode[vertexNum]();  //建立顶点数组
                for(int idx=0;idx!=vertexNum;++idx)
                {
                        vertexArr[idx].data = idx;
                        vertexArr[idx].in = g.getInputDegree(idx);  //获取入度
                        vertexArr[idx].firstEdge = nullptr;
                }
                for(int idx=0;idx!=vertexNum;++idx)
                {
                        for(int iidx=0;iidx!=vertexNum;++iidx)
                        {
                                if(1==g.getGraphEdgeWeight(idx,iidx))
                                {
                                        edgeNode* tmp = new edgeNode();
                                        tmp->vertexIdx = iidx;
                                        tmp->next = vertexArr[idx].firstEdge;
                                        vertexArr[idx].firstEdge = tmp;
                                }
                        }
                }
        }
        int TopologicalSort_AOV(const meihao::Graph& g)
        {
                stack<int> zeroInputDegreeVertex;
                int vertexNum = g.getGraphVertexNumber();
                vertexNode* vertexArr = nullptr;  //建立顶点表数组
                initDataStruct(g,vertexArr);  //建立顶点边和对应的边表
                for(int idx=0;idx!=vertexNum;++idx)
                {
                        if(0==vertexArr[idx].in)
                        {
                                zeroInputDegreeVertex.push(idx);
                        }
                }
                //遍历输出拓扑排序
                int cnt = 0;  //统计拓扑排序输出的点数,如果cnt最后不等于图的顶点数,说明不是AOV
                while(!zeroInputDegreeVertex.empty())
                {
                        int idx = zeroInputDegreeVertex.top();
                        cout<<vertexArr[idx].data<<" ";  //输出一个度为0的顶点
                        zeroInputDegreeVertex.pop();
                        ++cnt;
                        for(edgeNode* node = vertexArr[idx].firstEdge;nullptr!=node;node=node->next)
                        { //删除了一个度为0的顶点,对应其出边表中的顶点的入得要减1
                                vertexArr[node->vertexIdx].in--;
                                if( 0==(vertexArr[node->vertexIdx].in) )
                                        zeroInputDegreeVertex.push( node->vertexIdx );
                        }
                }
                if(vertexNum==cnt)
                        return 0;
                else
                        return -1;
        }
};

图的拓扑排序,AOV,完整实现,C++描述的更多相关文章

  1. 【bzoj5017】[Snoi2017]炸弹 线段树优化建图+Tarjan+拓扑排序

    题目描述 在一条直线上有 N 个炸弹,每个炸弹的坐标是 Xi,爆炸半径是 Ri,当一个炸弹爆炸时,如果另一个炸弹所在位置 Xj 满足:  Xi−Ri≤Xj≤Xi+Ri,那么,该炸弹也会被引爆.  现在 ...

  2. 拓扑排序---AOV图

    对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序,是将G中全部顶点排成一个线性序列, 使得图中随意一对顶点u和v,若边(u,v)∈E(G),则u在线性序列中出如 ...

  3. AOV图与拓扑排序&AOE图与关键路径

    AOV网:所有的工程或者某种流程可以分为若干个小的工程或阶段,这些小的工程或阶段就称为活动.若以图中的顶点来表示活动,有向边表示活动之间的优先关系,则这样活动在顶点上的有向图称为AOV网. 拓扑排序算 ...

  4. 数据结构之---C语言实现拓扑排序AOV图

    //有向图的拓扑排序 //杨鑫 #include <stdio.h> #include <stdlib.h> #include <string.h> #define ...

  5. C#实现有向无环图(DAG)拓扑排序

    对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若边(u,v)∈E(G),则u在线性序列中出现在 ...

  6. POJ - 3249 Test for Job (在DAG图利用拓扑排序中求最长路)

    (点击此处查看原题) 题意 给出一个有n个结点,m条边的DAG图,每个点都有权值,每条路径(注意不是边)的权值为其经过的结点的权值之和,每条路径总是从入度为0的点开始,直至出度为0的点,问所有路径中权 ...

  7. 【数据结构】【图文】【oj习题】 图的拓扑排序(邻接表)

    拓扑排序: 按照有向图给出的次序关系,将图中顶点排成一个线性序列,对于有向图中没有限定次序关系的顶点,则可以人为加上任意的次序关系,由此所得顶点的线性序列称之为拓扑有序序列.显然对于有回路的有向图得不 ...

  8. Paint the Grid Again (隐藏建图+优先队列+拓扑排序)

    Leo has a grid with N × N cells. He wants to paint each cell with a specific color (either black or ...

  9. 【NOIP2017】逛公园(最短路图,拓扑排序,计数DP)

    题意: 策策同学特别喜欢逛公园. 公园可以看成一张 N 个点 M 条边构成的有向图,且没有自环和重边.其中 1 号点是公园的入口, N 号点是公园的出口,每条边有一个非负权值,代表策策经过这条边所要花 ...

随机推荐

  1. Python splinter 环境搭建

    今天无意间看到了splinter. Splinter是一个使用Python开发的开源Web应用测试工具.它可以帮你实现自动浏览站点和与其进行交互. Splinter对已有的自动化工具(如:Seleni ...

  2. Asp.net core 学习笔记 ( User Secrets )

    参考 : http://cnblogs.com/nianming/p/7068253.html https://docs.microsoft.com/en-us/aspnet/core/securit ...

  3. 第 2 章 容器架构 - 008 - Docker 组件如何协作?

    容器启动过程如下: Docker 客户端执行 docker run 命令. Docker daemon 发现本地没有 httpd 镜像. daemon 从 Docker Hub 下载镜像. 下载完成, ...

  4. Pytorch Visdom可视化工具

    2018-12-04 14:05:49 Visdom是Facebook专门为PyTorch开发的一款可视化工具,其开源于2017年3月.Visdom十分轻量级,但却支持非常丰富的功能,能胜任大多数的科 ...

  5. using 自动释放资源示例

    我们在使用SqlConnection的时候可以加入using,那么在using语句结束后就会自动关闭连接.那么这种情况是怎么是实现的呢?我们能够自己写一个类似于SqlConnection的类来让usi ...

  6. legend2---开发日志5(如何解决插件的延迟问题,比如vue)

    legend2---开发日志5(如何解决插件的延迟问题,比如vue) 一.总结 一句话总结:元素可以先设置为隐藏,这样就不会让用户看到延迟的问题,然后等加载完再显示, 元素先设置为隐藏 加载完再显示 ...

  7. 雷林鹏分享:XML to HTML

    XML to HTML 在 HTML 页面中显示 XML 数据 在下面的实例中,我们打开一个 XML 文件("cd_catalog.xml"),然后遍历每个 CD 元素,并显示HT ...

  8. gcc优化引起get_free_page比__get_free_page返回值多4096

    2017-12-12 18:53:04 gcc优化引起get_free_page比__get_free_page返回值多4096 内核版本:1.3.100 extern inline unsigned ...

  9. Spring Batch 批量处理策略

    为了帮助设计和实现批量处理系统,基本的批量应用是通过块和模式来构建的,同时也应该能够为程序开发人员和设计人员提供结构的样例和基础的批量处理程序. 当你开始设计一个批量作业任务的时候,商业逻辑应该被拆分 ...

  10. IE的“浏览器模式”和“文档模式的区别”

    1.浏览器模式 用于切换IE针对该网页的默认文档模式.对不同版本浏览器的条件备注解析.发送给网站服务器的用户代理(User_Agent)字符串的值.网站可以根据浏览器返回的不同用户代理字符串判断浏览器 ...