关键路径问题--完美版

#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;

}

时间: 2024-12-09 19:10:15

关键路径问题--完美版的相关文章

麦当劳优惠券客户端应用源码完美版

麦当劳优惠券客户端应用源码完美版,该源码比较完整的,基本实现了常用的点餐订餐的功能了,大家可以参考一下吧. 应用说明: 能省钱的必备软件,占用资源少,起码可装个备用. *可直接使用,不需要打印,非常方便* 选好你需要的套餐,向柜台服务员展示即可 全国麦当劳通用.上海.广州.张家口.绵阳.青岛.深圳. 天津.北京.武.汕头.宝鸡.南京.呼和浩特.四川泸州.山西太原,以上城市已有热心网友验证可用电子券杭州.厦门麦当劳亲测可用 <ignore_js_op> 133302589.jpg (59.39

Android scrollview 上滑固定某一控件(美团团购详情UI)完美版

在scrollview 上滑固定某一控件(美团团购详情UI)文中介绍了怎么用touchlistener实现类似上滑停住的效果,但是这种方法存在一个明显的bug,就是在内容比较多的时候, 大部分人都是以滑动方式查看内容,而不是touch的方式,这就会导致最上面的滑块出现不及时,或者延后的现象,这里介绍一个全新的方法去实现类似效果,可以很好的解决以上问题. 目前在scrollview中没有onscrolllistener所以需要自己去实现,先复写一个scrollview: package com.e

轻量、强大的代码编辑器控件-WinForm完美版

前段时间做个小项目需要用到一个代码编辑器控件,但网上搜了半天,居然没发现一个完全满意的编辑器.现有的一些编辑器有: FastedTextBox 优点:1.  轻量. 2. 样式美观. 3. DEMO完整,文档丰富. 缺点:1. 不支持中文/中文字体显示难看 2. 代码折叠只能支持整行. ICSharpCode.AvalonEdit 优点:功能强大,几乎完美,非常接近 VS 缺点:1. 使用 WPF 开发. 2. 在 WinForm 使用不大稳定,比如不能同时开两个窗口,图形错位. 3. 内存多.

hexo + github 从零搭建 windows 傻瓜式 完美版

这里介绍的windows 下 安装 废话不说,开始 1.安装NodeJs Hexo需用通过npm安装,而npm需要node,现在只要安装node 就自带 npm了 下载地址 (说明:LTS为长期支持版,Current为当前最新版) //下载LTS就好了 安装步骤:反正下载好msi文件后,双击打开安装,也是一路next 打开cmd控制台 查看版本: 命令:node -v 这里需要把npm 换成淘宝的镜像,不然装插件会很慢,和装不上 npm install -g cnpm --registry=ht

SVN安装配置与使用(完美版)

1.  所选server安装包:VisualSVN-Server-2.1.3.msi. 2.  client安装包:TortoiseSVN-1.6.2.16344-win32-svn-1.6.2.msi 一.server的安装: 注意:location :为安装文件位置,Repositories:为管理的代码仓库的位置,若选中Use secure connection前面的Checkbox,则表示安全连接[https].这里的port有433/8433可用,若未选中Checkbox.默认port

拖拽完美版2016/4/22

function Drag(obj) { obj.onmousedown=function(ev) { var ev=ev||event; var disX=ev.clientX-obj.offsetLeft; var disY=ev.clientY-obj.offsetTop; if(obj.setCapture) { obj.setCapture(); } document.onmousemove=function(ev) { var ev=ev||event; obj.style.left

完美版—缓冲运动框架

//末尾有获取当前样式的方法function startMove(obj,json,endFn){ clearInterval(obj.timer); obj.timer = setInterval(function(){ var bBtn = true; for(var attr in json){ var iCur = 0; if(attr == 'opacity'){ if(Math.round(parseFloat(getStyle(obj,attr))*100)==0){ iCur =

Dom++完美版得到元素到html的距离6/4/21

function getTop(obj) { var pos={left:0,top:0}; while(obj) { pos.left+=obj.offsetLeft; pos.top+=obj.offsetTop; obj=obj.offsetParent; } return pos; }

1014 词法分析器(完美版)

#include<stdio.h> #include <string.h> #include<iostream.h> main(){ char a[10000]; char ch,bh; int i,s,t,j,q; s=0; t=0; printf("请输入字符(输入#结束):"); do { scanf("%c",&ch); a[s++]=ch; }while(ch!='#'); for(i=0;i<s;i++)