关键路径问题--完美版
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define Maxv 50
#define Maxvexnum 100
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW -2
#define Sinitsize 100 //栈存储空间初始分配
#define Sincrement 50 //栈存储空间分配增
int ve[Maxvexnum];//存放最早发生时间
typedef char Vertextype[Maxv]; //顶点向量
typedef int Selemtype;
typedef int Status;
/*
www.quzhuanpan.comp
解释权来自去转盘网,转载请告知
*/
typedef struct Arcnode
{
int adjvex; //该弧所指向的顶点的位置
struct Arcnode *nextarc; //指向下一条弧的指针
int weight;
} Arcnode; //储弧的信息存
typedef struct
{
Vertextype data; //顶点信息
Arcnode *firstarc; //第一个表结点的地址,指向第一条依附该顶点的弧的指针
} Vnode,Adjlist[Maxvexnum]; //头结点
typedef struct
{
Adjlist vertexs;
int vexnum,arcnum;
} Algraph;
/*
www.quzhuanpan.comp
解释权来自去转盘网,转载请告知
*/
typedef struct
{
Selemtype *base;
Selemtype *top;
int stacksize;
} Sqstack;
int Locatevex(Algraph &G,Vertextype u)//字符型的u
{
int i;
for(i = 0; i < G.vexnum; ++i)
if(strcmp(u,G.vertexs[i].data) == 0)
return i;
return OK;
}//all right
/*Status Listinsert(Algraph &G,int i,Arcnode *e) //在不带头结点的单链表L中第i个位置之前插入元素e
{
e->nextarc =&L;
L =*e;
return OK;
}*/
int Creategraph(Algraph &G)
{
int i,j,k,w;
Vertextype V1,V2;
Arcnode *e;
printf("请输入图的顶点数,边数(以空格作为间隔):\n");
scanf("%d%d",&G.vexnum,&G.arcnum);
printf("请输入%d个顶点的值(小于%d个字符):\n",G.vexnum,Maxv);
for(i = 0; i<G.vexnum; ++i) //构造顶点向量并初始化
{
scanf("%s",G.vertexs[i].data);
G.vertexs[i].firstarc = NULL;
}
printf("请输入%d条弧的弧尾,弧头和权值(以空格作为间隔):\n",G.arcnum);
for(k = 0; k < G.arcnum; ++k)
{
scanf("%s%s%d",V1,V2,&w);
i = Locatevex(G,V1);
j = Locatevex(G,V2);
e = (Arcnode *)malloc(sizeof(Arcnode)); //:为每条弧分配内存,插入链表
e->weight = w;
e->adjvex = j;
e->nextarc = NULL;
//Listinsert(G.vertexs[i].firstarc,1,&e);
e->nextarc=G.vertexs[i].firstarc;
G.vertexs[i].firstarc=e;
}
return OK;
}
/*
www.quzhuanpan.comp
解释权来自去转盘网,转载请告知
*/
int Display(Algraph &G)
{
int i;
Arcnode *p;
printf("\n\n");
printf("%d个顶点:",G.vexnum);
for(i = 0; i < G.vexnum; ++i)
{
printf("%s ",G.vertexs[i].data);
}
printf("\n\n\n");
printf("%d条弧:\n",G.arcnum);
for(i = 0; i < G.vexnum; ++i)
{
p = G.vertexs[i].firstarc;
while(p)
{
printf("%5s%5s%5d\n",G.vertexs[i].data,G.vertexs[p->adjvex].data,p->weight);
p = p->nextarc;
}
}
return OK;
}
void Findindegree(Algraph &G,int indegree[])
{
int i;
Arcnode *p;
for(i = 0; i < G.vexnum; ++i)
indegree[i] = 0;
for(i = 0; i < G.vexnum; ++i)
{
p = G.vertexs[i].firstarc;
while(p)
{
indegree[p->adjvex]++;
p = p->nextarc;
}
}
}
void Initstack(Sqstack &S)
{
S.base = (Selemtype *)malloc(Sinitsize * sizeof (Selemtype));
if(!(S.base))
exit(OVERFLOW);
S.top = S.base;
S.stacksize = Sinitsize;
}
Status Stackempty(Sqstack &S)
{
if(S.top == S.base)
return TRUE;
else return ERROR;
}
void Push(Sqstack &S,int &e)
{
if(S.top -S.base >= S.stacksize)
{
S.base = (Selemtype *)realloc(S.base,(S.stacksize + Sincrement) * sizeof(Selemtype));
if(!(S.base))
exit(OVERFLOW);
S.top = S.base + S.stacksize;
S.stacksize += Sincrement;
}
*(S.top)++ = e;
}
Status Pop(Sqstack &S,int &e)
{
if(S.top == S.base)
return ERROR;
e = *(--S.top);
return OK;
}
Status TopologicalOrder(Algraph &G, Sqstack &T)
{
int count1=0;
int count2=0;
int i,k,N=0;
int indegree[Maxvexnum];
Sqstack S;
Arcnode *p;
Findindegree(G,indegree);
Initstack(S);
for(i = 0; i < G.vexnum; ++i)
{
if(indegree[i]==0)
{
Push(S,i); //入度为零者进栈
count1++;
}
if(G.vertexs[i].firstarc==NULL)
N++;
}
if(count1>1)
{
printf("图中有%d个源点,不能找出关键路径!!!\n",count1);
return 0;
}
else if(N>1)
{
printf("图中有%d个汇点,不能找出关键路径!!!\n",N);
return 0;
}//一个活动只有一个开始和一个结尾,故源点和汇点只可是一
printf("\n");
printf("拓扑序列:");
Initstack(T);
for(i = 0; i < G.vexnum; ++i)
ve[i] = 0;
while(!Stackempty(S))
{
Pop(S,i);
printf("%s ",G.vertexs[i].data);
Push(T,i);
++count2; //对输出顶点计数
for(p = G.vertexs[i].firstarc; p; p = p->nextarc)
{
k = p->adjvex; //对i号顶点的每个邻接点的入度减一
if(--indegree[k] == 0)
Push(S,k);
if(ve[i] + p->weight > ve[k])
ve[k] = ve[i] + p->weight;
}
}
printf("\n\n");
if(count2 < G.vexnum)
{
printf("此有向网有回路\n");
return 0;
}
else return 1;
}
Status CriticalPath(Algraph &G)
{
int vl[Maxvexnum];
Sqstack T;
int i,j,k,ee,el,dut;
Arcnode *p;
if(!TopologicalOrder(G,T))
return 0;//如果返回不是1,后面的不执行
j= ve[0];
for(i = 0; i < G.vexnum; i++)
if(ve[i] > j)
j = ve[i];//终点的活动对应的最早发生时间
for(i = 0; i < G.vexnum; i++)
vl[i] = j;//全部赋值成终点的活动对应的最早发生时间
while(!Stackempty(T))
{
for(Pop(T,j),p = G.vertexs[j].firstarc; p ; p = p->nextarc)
{
k = p->adjvex;
dut = p->weight;
if(vl[k] - dut < vl[j])
vl[j] = vl[k] - dut;
}//栈T里面放的是逆拓扑序列,即放了对应的下标
}
printf("V ve[i] vl[i]\n");
for(i = 0; i < G.vexnum; ++i)
{
printf("%s %d %5d",G.vertexs[i].data,ve[i],vl[i]);
if(ve[i] == vl[i])
printf(" 关键路径经过的顶点");
printf("\n");
}
printf("\n");
printf("注释:V为事件,ve[i]为最早开始时间,vl[i]为最迟开始时间。\n");
printf("\n");
printf("j----k----权值----ee----el\n");
for(j = 0; j < G.vexnum; ++j) //求ee,el和关键活动
for(p = G.vertexs[j].firstarc; p ; p = p->nextarc)
{
k = p->adjvex;
dut = p->weight;
ee = ve[j];
el = vl[k] - dut;
printf("%s-->%s %3d %5d %5d ",G.vertexs[j].data,G.vertexs[k].data,dut,ee,el);
if(ee == el)
printf("关键活动");
printf("\n");
}//for
printf("\n注释:ee为活动的最早开始时间,el为活动的最迟开始时间。");
j--;
printf("\n\n");
printf("完成整项工程需要时间为:%d",ve[j]);
printf("\n");
return OK;
}
/*
www.quzhuanpan.comp
解释权来自去转盘网,转载请告知
*/
int main()
{
system("color 5f");
Algraph h;
Creategraph(h);
Display(h);
CriticalPath(h);
return 0;
}
转载于:https://blog.51cto.com/5912119/1734724
关键路径问题--完美版相关推荐
- java 创建日程到期提醒_苹果“快捷指令”日程播报完美版
日程播报是一个常见于"快捷指令"中"早安/晚安"场景中的一项功能.通过与Win10日历时刻同步,可以非常方便的安排未来行程,避免遗忘重要事项.比如这样 每天早上 ...
- java企业人事管理系统源码_企业人事管理系统完美版源代码 - 源码下载|行业应用软件|企业管理(财务/ERP/EIP等)|源代码 - 源码中国...
企业人事管理系统完美版源代码 ............................\DataEnvironment.DCA ............................\DataEnv ...
- Z-BlogPHP导航主题模版源码 绿色完美版
介绍: Z-BlogPHP导航主题绿色完美版! 内附详细安装使用说明TXT文档! 网盘下载地址: http://kekewl.org/xmlaj45mJLC0 图片:
- VSCode 调试 Egg 完美版 - 进化史 #25
VSCode 调试 Egg 完美版 - 进化史 #25 背景 VSCode 早期版本,对 Node Cluster 的调试支持一直不是很友好,譬如: 开发期重启进程后,不支持重新 attach. Cl ...
- 计算机打音乐光辉岁月,光辉岁月(完美版)
Introduction <光辉岁月>是中国香港摇滚乐队Beyond演唱的一首歌曲,由黄家驹作曲并为歌曲的粤语版填词,国语版则由何启弘.周治平填词.该曲的粤语.国语版分别收录在Beyond ...
- 解忧云SMS短信发送系统服务平台源码+解密完美版
正文: 解忧云SMS短信服务平台系统,短信发送系统,全解密完美版,经过一系列修复现在程序已经可以完全使用. 并且是全解密随时可以二开,无后门,一些bug已经完全修复. 安装教程: 数据库配置文件路径 ...
- flutter整合极光推送完美版
flutter整合极光推送完美版 这篇博文讲的是flutter整合极光推送,也就是jpush,看完包你会. 一.加入极光配置 1.pubspec.yaml jpush_flutter: ^2.0.5 ...
- 乐2的android版本,乐视2高通|MIUI10|安卓6.0|最终完美版|极速_最新最全的乐2高通版ROM刷机包下载、刷机...
乐视2高通|MIUI10|安卓6.0|最终完美版|极速流畅|稳定实用|摇晃手势|DDK设置|养老专用 更新编译工具ROM体积更小相机切换不卡 因为Magisk的关系开机会有系统提示完全不影响 精简桌面 ...
- 2023 txl短信相册通讯录APP获取 双端完美版
2023 txl短信相册通讯录APP获取 双端完美版........... ....................
最新文章
- C语言中的位运算和逻辑运算
- kafka不使用自带zk_kafka 安装部署教程
- 关于ZIP大文件压缩
- Exchange 2016 先决条件
- C#dC# 简单网页外挂实例
- 推荐2个十分好用的pandas数据探索分析神器!
- java桌面应用程序打包为exe
- 计算机一级文档题,计算机一级模拟题
- 在Play上使用twitter4j! 框架和安全社交很容易
- key_t IPC键和ftok函数详解和剖析
- 【C语言】数组名作函数参数完成数据的升序排列
- 数据结构与算法(刺猬书)读书笔记----目录
- 高品质静物空间海报模板PSD分层素材
- 右键新建Excel时如何设定其版本即.xlsx转.xls格式
- 使用阿里云镜像加速器为docker pull提速
- epub.js制作电子书阅读网站
- python xlrd 错误:xlrd.biffh.XLRDError: Unsupported format, or corrupt file: Expected BOF reco
- 计算机无法正常更新,无法完成更新正在撤销更改请不要关闭你的计算机的解决方法...
- ArrayList源码解读
- linux crontab在线生成,linux下crontab在线配置解析 互联网技术圈 互联网技术圈