您的位置:首页 > 其它

AOE网咯与关键路径

2014-10-26 19:33 344 查看
测试节点如下:



测试数据如下:

1 2 6

1 3 4

1 4 5

2 5 1

3 5 1

5 7 9

5 8 7

4 6 2

6 8 4

7 9 2

8 9 4

测试代码如下:(加注释)

/**
拓补排序的实现,使用邻接链表存储有向图
*/
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
using namespace std;
#define MAX 9+1
struct inNode{
int value;
int key_node;
struct inNode *next;
};
struct outNode{
int value;
int key_node;
struct outNode *pre;
};
struct in_degree{
int key_node;
struct inNode *head;
};

struct out_degree{
int key_node;
struct outNode *head;
};
//定义全局变量
struct in_degree inList[MAX];
struct out_degree outList[MAX];
int inCount[MAX],outCount[MAX];
void init()
{
int i;
int m,n,value;
struct inNode *p,*p1;
struct outNode *q,*q1;
memset(inCount,0,sizeof(inCount));
memset(outCount,0,sizeof(outCount));
for(i=0;i<MAX;i++)
{
inList[i].key_node=i;
inList[i].head=NULL;
outList[i].key_node=i;
outList[i].head=NULL;
}
freopen("input.txt","r",stdin);
while(~scanf("%d%d%d",&m,&n,&value))
{
p1=(struct inNode*)malloc(sizeof(struct inNode));
q1=(struct outNode*)malloc(sizeof(struct outNode));
p1->key_node = n;
q1->key_node = m;
p1->value=q1->value = value;
p1->next=NULL;
q1->pre=NULL;
if(inList[m].head!=NULL)
{
p=inList[m].head;
while(p->next!=NULL)
p=p->next;
p->next=p1;
}
else
inList[m].head = p1;
inCount
++;

if(outList
.head!=NULL)
{
q=outList
.head;
while(q->pre!=NULL)
q=q->pre;
q->pre=q1;
}
else
outList
.head = q1;
outCount[m]++;
}
return;
}

void AOE()
{
//方法:第一:根据拓扑序列求出每一个事件最早发生的时间eN;
//第二:根据逆拓扑序列求出每一个时间最晚发生的时间lN;
//第三:判断最早的时间和最晚的时间是否相等,
//第四:给出关键路径
int eN[MAX],lN[MAX];
int queue[MAX],top = -1,bottom=-1;
int current;
struct inNode *inp;
struct outNode *outp;

memset(eN,0,sizeof(eN));
memset(lN,0,sizeof(lN));
memset(queue,0,sizeof(queue));
//首先将源点加入
queue[++top]=1;
while(top != bottom)
{
current = queue[++bottom];
inp = inList[current].head;
while(inp!=NULL)
{
eN[inp->key_node]=max(eN[inp->key_node],eN[current]+inp->value);
if(--inCount[inp->key_node] == 0)
queue[++top] = inp->key_node;
inp=inp->next;
}
}

int k = lN[MAX-1] = eN[MAX-1];//任务总的时间固定
for(int i=0;i<MAX;i++)
lN[i]=k;
//首先将汇点加入
memset(queue,0,sizeof(queue));
top=bottom=-1;
queue[++top]= MAX-1;
while(top != bottom)
{
current = queue[++bottom];
outp = outList[current].head;
while(outp!=NULL)
{
lN[outp->key_node] = min(lN[outp->key_node],eN[current]-outp->value);
if(--outCount[outp->key_node] == 0)
queue[++top] = outp->key_node;
outp = outp->pre;
}
//这里比较eN和lN就直接进行了
if(lN[current] == eN[current])
printf("节点:%d\n",current);
}
return ;
}
int main()
{
init();
AOE();
return 0;
}
测试结果如下:


关键点,两个邻接链表,一个存储拓扑序列,一个存储逆拓扑序列!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息