#include <stdio.h>
#include <stdlib.h>
#include <string.h>//我这里的头以及尾巴与书上的不一样。
int max(int a, int b)
{
return a > b?a:b;
}
int min(int a, int b)
{
return a < b?a:b;
}
typedef struct ArcNode
{
int from, to;
struct ArcNode * fnext, *tonext;
int w;
}ArcNode;
typedef struct VertexNode
{
char info;
ArcNode *ff, *ft;
}VertexNode;
typedef struct Graph
{
int num_vertex;
int num_arc;
VertexNode *ver;
}Graph;
Graph *Create(int n)
{
Graph * G = (Graph*)malloc(sizeof(Graph));
G->num_vertex = n;
G->num_arc = 0;
G->ver = (VertexNode*)calloc(n+1, sizeof(VertexNode));
for(int i = 1; i <= n; i++)
{
G->ver[i].ff = NULL;
G->ver[i].ft = NULL;//在这里可以补加点的信息
}
return G;
}
void AddArc(Graph *G,int a, int b, int c)
{
(G->num_arc)++;
ArcNode *s = (ArcNode*)malloc(sizeof(ArcNode));
s->from = a;
s->to = b;
s->fnext = G->ver[a].ff;
G->ver[a].ff = s;
s->tonext = G->ver[b].ft;
G->ver[b].ft = s;
s->w = c;
} //手写一个栈
typedef struct stack{
int *data;
int cnt;
int max;
}Stack;
Stack *Create_Stack(int max)
{
Stack *s = (Stack*)malloc(sizeof(Stack));
s->cnt = -1;
s->data = (int *)calloc(max, sizeof(int));
s->max = max;
return s;
}
void Pop_Stack(Stack *S)
{
if(S->cnt > -1)
S->cnt--;
}
void Push_Stack(Stack *S, int e)
{
if(S->cnt < S->max)
{
S->cnt++;
S->data[S->cnt] = e;
}
}
int Top_Stack(Stack *S)
{
if(S->cnt > -1)
{
return S->data[S->cnt];
}
return 0x3f3f3f3f;
}
void Destory_Stack(Stack *S)
{
free(S->data);
free(S);
}
int Empty_Stack(Stack *S)
{
if(S->cnt == -1)
return 1;
return 0;
} //进行topo排序
int TopoSort(Graph *G, int *arr)
{
int total = 0;
Stack* s = Create_Stack(G->num_vertex+2);
int *in = (int *)calloc(G->num_vertex+1,sizeof(G));
for(int i = 1; i <= G->num_vertex; i++)
{
int cnt = 0;
for(ArcNode *A = G->ver[i].ft; A; A = A->tonext)
cnt++;
in[i] = cnt;
if(cnt == 0)
Push_Stack(s, i);
}
while(!Empty_Stack(s))
{
int t = Top_Stack(s);
arr[++total] = t;
Pop_Stack(s);
for(ArcNode *A = G->ver[t].ff; A; A = A->fnext)
{
in[A->to]--;
if(in[A->to]==0)
Push_Stack(s, A->to);
}
}
free(in);
Destory_Stack(s);
if(total != G->num_vertex)
return 1;
return 0;
} void AOE(Graph *G)
{
int *topo = (int *)calloc(G->num_vertex+2, sizeof(int));
int *ve = (int *)calloc(G->num_vertex+1, sizeof(int));
int *vl = (int *)calloc(G->num_vertex+1, sizeof(int));
for(int i = 1; i <= G->num_vertex; i++)
{
ve[i] = 0;
vl[i] = 0x3f3f3f3f;
}
if(TopoSort(G, topo))
printf("该任务出现闭环!!!");
//计算ve ve[1] = 0; for(int i = 2; i <= G->num_vertex; i++)//注意是以2开始
{
for(ArcNode *A = G->ver[topo[i]].ft; A; A = A->tonext)
{
ve[topo[i]] = max(ve[topo[i]],ve[A->from]+A->w);
}
}
//计算vl
vl[G->num_vertex] = ve[G->num_vertex];
for(int i = G->num_vertex; i >= 1; i--)
{
for(ArcNode *A = G->ver[topo[i]].ft; A; A = A->tonext)
{
vl[A->from] = min(vl[A->from], vl[A->to]-A->w);
}
}
for(int i = 1; i <= G->num_vertex; i++)
{
for(ArcNode *A = G->ver[topo[i]].ff; A; A = A->fnext)
{
printf("%d ----> %d:\n",A->from, A->to);
printf("最早:%d\t最迟:%d\t",ve[A->from], vl[A->to]-A->w);
if(ve[A->from]==vl[A->to]-A->w)
printf("关键活动\n");
else
printf("非关键活动,松弛时间:%d\n",vl[A->to]-A->w-ve[A->from]);
}
}
free(topo);
free(ve);
free(vl);
}
int main()//要求:第一个序号代表源点, 最后一个(n号)代表汇点
{
//要求:第一个序号代表源点, 最后一个(n号)代表汇点
//要求:第一个序号代表源点, 最后一个(n号)代表汇点
//要求:第一个序号代表源点, 最后一个(n号)代表汇点
int n,m;
scanf("%d",&n);
Graph *G = Create(n);
scanf("%d",&m);
for(int i = 1; i <= m; i++)
{
int a,b,c;
scanf("%d%d%d",&a, &b, &c);
AddArc(G,a,b,c);
}
AOE(G);
return 0;
}
/*测试用例
9 11
1 2 6
1 3 4
1 4 5
2 5 1
3 5 1
4 6 2
5 7 9
5 8 7
6 8 4
8 9 4
7 9 2 */

AOV网的实现(数据结构)的更多相关文章

  1. 算法与数据结构(八) AOV网的关键路径

    上篇博客我们介绍了AOV网的拓扑序列,请参考<数据结构(七) AOV网的拓扑排序(Swift面向对象版)>.拓扑序列中包括项目的每个结点,沿着拓扑序列将项目进行下去是肯定可以将项目完成的, ...

  2. 算法与数据结构(七) AOV网的拓扑排序

    今天博客的内容依然与图有关,今天博客的主题是关于拓扑排序的.拓扑排序是基于AOV网的,关于AOV网的概念,我想引用下方这句话来介绍: AOV网:在现代化管理中,人们常用有向图来描述和分析一项工程的计划 ...

  3. 算法与数据结构(八) AOV网的关键路径(Swift版)

    上篇博客我们介绍了AOV网的拓扑序列,请参考<数据结构(七) AOV网的拓扑排序(Swift面向对象版)>.拓扑序列中包括项目的每个结点,沿着拓扑序列将项目进行下去是肯定可以将项目完成的, ...

  4. 算法与数据结构(七) AOV网的拓扑排序(Swift版)

    今天博客的内容依然与图有关,今天博客的主题是关于拓扑排序的.拓扑排序是基于AOV网的,关于AOV网的概念,我想引用下方这句话来介绍: AOV网:在现代化管理中,人们常用有向图来描述和分析一项工程的计划 ...

  5. AOV网与拓扑排序

    在一个表示工程的有向图中,用顶点表示活动,用弧表示活动之间的优先关系,这样的有向图为顶点表示活动的网,我们称之为AOV网(Activity on Vextex Network).AOV网中的弧表示活动 ...

  6. 有向无环图的应用—AOV网 和 拓扑排序

    有向无环图:无环的有向图,简称 DAG (Directed Acycline Graph) 图. 一个有向图的生成树是一个有向树,一个非连通有向图的若干强连通分量生成若干有向树,这些有向数形成生成森林 ...

  7. 慕课网:C++ & 数据结构

    课程链接:james_yuan的课程 这部分太枯燥了,如果教材难度稍大,根本就学不下去,所以就先看看通俗的视频吧. 课程目录 1.C++远征之起航篇 - C++亮点尽在其中 2.C++远征之离港篇 - ...

  8. AOV网

    1.定义 用顶点表示活动,用有向边<Vi, Vj>表示活动间的优先关系. Vi必须先于活动Vj进行. 这种有向图叫做顶点表示活动的AOV网络(Activity On Vertices) 2 ...

  9. AOE网与AOV网

    因为有人无端怀疑此博客为抄袭, 且作者写作此博客时仅为应试之用,今毕业已久此文章已无用处 故删除文章,不想再无故受到打扰 祝好

随机推荐

  1. 图文详解:小白也能看懂的 Kubernetes

    Kubernetes 这个单词来自于希腊语,含义是舵手或领航员 .其词根是 governor 和 cybernetic.K8s 是它的缩写,用 8 字替代了"ubernete". ...

  2. 【面试普通人VS高手系列】讲一下wait和notify这个为什么要在synchronized代码块中?

    一个工作七年的小伙伴,竟然不知道"wait"和"notify"为什么要在Synchronized代码块里面. 好吧,如果屏幕前的你也不知道,请在评论区打上&qu ...

  3. Markdown基础语法(上)

    前言 按照官方文档,和根据自己所用和所理解所写 一.标题语法 一级标题最大,六级标题最小 # 一级标题 ## 二级标题 ### 三级标题 #### 四级标题 ##### 五级标题 ###### 六级标 ...

  4. Python 什么是flask框架?快速入门

    一:Python flask框架 前言 1.Python 面向对象的高级编程语言,以其语法简单.免费开源.免编译扩展性高,同时也可以嵌入到C/C++程序和丰富的第三方库,Python运用到大数据分析. ...

  5. windows 存储和切换 ip 配置

    我的虚拟机用的是桥接模式,在公司使用时设置的是静态 ip,但网段和家里面的不一样,就导致在公司和家里,我需要频繁修改 ipv4 的配置以适应不同的网络环境 Simple-IP-Config 工具解决了 ...

  6. linux篇-新建svn仓库

    1昨天需要在服务器上新建一个仓库,解决方法是把已有的仓库拷贝出来,库删除在放进去 2然后今天想看看有没有命令的方法 find / -name project 首先查看一下项目的位置 3创建仓库 svn ...

  7. K8S Calico网络插件

    0.前言 参考文档:https://github.com/containernetworking/cni Pod网络插件,为了实现Pod网络而需要的插件.组件.由于Kubernetes通过开放的CNI ...

  8. 【单片机】NB-IoT移远BC28调试笔记

    一.入网总体思路 入网思路是参考 <Quectel_BC95&BC35-G&BC28_应用设计指导_V1.1.pdf>来做的.流程如图所示: 二.具体调试细节3.1 AT+ ...

  9. 目标检测复习之Loss Functions 总结

    Loss Functions 总结 损失函数分类: 回归损失函数(Regression loss), 分类损失函数(Classification loss) Regression loss funct ...

  10. [NOI2011]阿狸打字机

    题意:一开始是个空串s,有三种操作:(1.末尾加一个字符 2.末尾减一个字符 3.存储该字符串) 思路: 一开始在trie树上动态加点很好处理,3操作的时候记录一下此时trie树上的pos,同时记录d ...