AOE网咯与关键路径

测试节点如下:

测试数据如下:

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[n]++;

        if(outList[n].head!=NULL)
        {
            q=outList[n].head;
            while(q->pre!=NULL)
                q=q->pre;
            q->pre=q1;
        }
        else
            outList[n].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;
}
测试结果如下:

关键点,两个邻接链表,一个存储拓扑序列,一个存储逆拓扑序列!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值