AOE网络的计算代码

//要求按顺序输入 
#include<stdio.h>
#include<string.h>
int n;
int a[100][100];//每个点的直接后继 
int b[100][100];//每个点的直接前驱
int ea[10000];//某个边的起点
int eb[10000];//某个边的终点 
int Ve[100];//事件的最早发生时间 
int Vl[100];//事件的最迟发生时间
int early[10000];//活动的最早开始时间
int late[10000];//活动的最迟发生时间
int le[10000];//活动余量 
bool guanjian[10000];//关键路径 
void dfs(int p)
{
    if (p==n)
    return;
    for (int i=p+1;i<=n;i++)
    {
        int temp;
        if (a[p][i]!=-1)
        {
            temp=Ve[p]+a[p][i];
            if (temp>Ve[i])
            {
                Ve[i]=temp;
            }
            dfs(i);
        }
    }
}
void dfs2(int p)
{
    if (p==1)
    return;
    for (int i=p;i>=1;i--)
    {
        int temp;
        if (b[p][i]!=-1)
        {
            temp=Vl[p]-b[p][i];
            if (temp<Vl[i])
            {
                Vl[i]=temp;
            }
            dfs2(i);
        }
    }
}
int main()
{
    scanf("%d",&n);
    
    int s,e,p;
    memset(a,-1,sizeof(a));
    memset(b,-1,sizeof(b));
    memset(ea,-1,sizeof(ea));
    memset(eb,-1,sizeof(eb));
    memset(guanjian,0,sizeof(guanjian));
    //将所有的有向边写入矩阵
    int m=0; 
    while (scanf("%d%d%d",&s,&e,&p))
    {
        m++;
        if (s==0)
        break;
        ea[m]=s;
        eb[m]=e; 
        a[s][e]=p;
        b[e][s]=p;//虽然只有一条边,但是我们可以这样来确保找到直接前驱 
    }
    m--;
    //求取每个顶点的Ve和Vl
    memset(Ve,0,sizeof(Ve));
    memset(Vl,0,sizeof(Ve));
    int start=1;
    dfs(1);
    printf("Ve:\n");
    for (int i=1;i<=n;i++)
    {
        Vl[i]=9999999;
        printf("%d ",Ve[i]);
    }
    Vl[n]=Ve[n];
    printf("\n");
    dfs2(n);
    printf("Vl:\n");
    for (int i=1;i<=n;i++)
    {
        printf("%d ",Vl[i]);
    }
    printf("\n");
    for (int i=1;i<=m;i++)
    {
        early[i]=Ve[ea[i]];
        late[i]=Vl[eb[i]]-a[ea[i]][eb[i]];
        le[i]=late[i]-early[i];
    }
    
    printf("edge  e   l   l-e\n");
    for (int i=1;i<=m;i++)
    {
        printf("%3d %3d %3d %3d\n",i,early[i],late[i],le[i]);
        
    }
    printf("所以关键路径是:\n");
    for (int i=1;i<=m;i++)
    {
        if (!le[i])
        {
            printf("a%d ",i);
        }        
    }
    printf("\n");
 } 

 

 

给出两组输入,分别对应下面的两幅图

输入一:

9
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
7 9 2
8 9 4
0 0 0
 

 

输入二:

13
1 2 1
1 3 6
1 4 3
1 5 4
1 6 3
1 7 1
2 9 6
3 9 2
4 9 7
4 11 6
4 12 8
5 8 5
5 12 11
6 8 10
6 13 21
7 8 6
8 9 4
8 10 9
8 11 4
9 12 8
10 11 9
11 12 3
11 13 12
12 13 10
0 0 0

图一

 

图二

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值