AOE网上的关键路径

AOE网上的关键路径

Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^

题目描述

    一个无环的有向图称为无环图(Directed Acyclic Graph),简称DAG图。
    AOE(Activity On Edge)网:顾名思义,用边表示活动的网,当然它也是DAG。与AOV不同,活动都表示在了边上,如下图所示:
                                     
    如上所示,共有11项活动(11条边),9个事件(9个顶点)。整个工程只有一个开始点和一个完成点。即只有一个入度为零的点(源点)和只有一个出度为零的点(汇点)。
    关键路径:是从开始点到完成点的最长路径的长度。路径的长度是边上活动耗费的时间。如上图所示,1 2 579是关键路径(关键路径不止一条,请输出字典序最小的),权值的和为18

输入

    这里有多组数据,保证不超过10组,保证只有一个源点和汇点。输入一个顶点数n(2<=n<=10000),边数m(1<=m <=50000),接下来m行,输入起点sv,终点ev,权值w1<=sv,ev<=n,sv != ev,1<=w <=20)。数据保证图连通。

输出

    关键路径的权值和,并且从源点输出关键路径上的路径(如果有多条,请输出字典序最小的)。

示例输入

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

示例输出

18
1 2
2 5
5 7
7 9

提示


#include<bits/stdc++.h>
using namespace std;
#define MAXN 10010
typedef struct ArcNode //链域
{
    int adjvex;//弧所指的顶点
    struct ArcNode *next;
    int weight; //权值,表活动时间
}ArcNode;
typedef struct Vnode//顶点域
{
    int data;
    ArcNode *firstarc;//指向第一条依附该顶点的弧的指针
}Vnode,AdjList[MAXN];
typedef struct
{
    AdjList vertices;
    int vexnum,arcnum;//图当前的顶点数和弧数
}ALGraph;
int indegree[MAXN];
int ve[MAXN];
int vl[MAXN];
int create(ALGraph &g)
{
    int i,j,k;
    int u,v,w;
    ArcNode *p;
    for(i=1;i<=g.vexnum;i++)
    {
        g.vertices[i].firstarc=NULL;
    }
    memset(indegree,0,sizeof(indegree));
    for(i=g.arcnum;i>=1;i--)
    {
        cin>>u>>v>>w;
        p=new ArcNode;
        indegree[v]++;
        p->adjvex=v;
        p->weight=w;
        p->next=g.vertices[u].firstarc;
        g.vertices[u].firstarc=p;
    }
    return 0;
}
stack<int >S2;
int CriticalPath(ALGraph g) //拓扑排序求最早发生时间ve[]
{

    stack<int >S1;
    ArcNode *p;
    int cnt=0;//用于记录顶点数
    memset(ve,0,sizeof(ve));
    for(int i=1;i<=g.vexnum;i++)
    {
        if(indegree[i]==0)
        S1.push(i);
    }
    while(!S1.empty())
    {
        int j=S1.top();
            S1.pop();
            S2.push(j);
            cnt++;
        p=g.vertices[j].firstarc;
        while(p)
        {
            if((--indegree[p->adjvex])==0)
            S1.push(p->adjvex);
            if(ve[j]+p->weight>ve[p->adjvex])
            {
                ve[p->adjvex]=ve[j]+p->weight;
            }
            p=p->next;
        }
    }
    
    /** 
    *用于检验最早发生时间是否正确
    */
    /*for(int i=1;i<=g.vexnum;i++)
    cout<<ve[i];*/
    if(cnt==g.vexnum)
        return 1;
    else
        return 0;
}

void CriticalActivity(ALGraph g) //逆拓扑排序求最迟发生时间vl[]
{
    if(!CriticalPath(g)) return ;
    ArcNode *p;
    for(int i=1;i<=g.vexnum;i++)
    {
        vl[i]=ve[g.vexnum];
    }
    while(!S2.empty())
    {
        int j=S2.top();
        S2.pop();
        p=g.vertices[j].firstarc;
        while(p)
        {
            if(vl[p->adjvex]-p->weight<vl[j])
            {
                vl[j]=vl[p->adjvex]-p->weight;
            }
            p=p->next;
        }
    }
    cout<<ve[g.vexnum]<<endl;
    ArcNode *q;
    int a,b,flag=0;
    /**
    *用于检验关键活动是否正确
    */
    /*for(int j=1;j<=g.vexnum;j++)
    cout<<vl[j]<<endl;*/
    for(int i=1;i<=g.vexnum;i++)
    {
        q=g.vertices[i].firstarc;
        while(q)  //求关键活动路径
        {
        int k=q->adjvex;
        int ee=ve[i];
        int el=vl[k]-q->weight;
        if(ee==el) //找到关键活动路径并按要求输出
        {
           if(flag==0)
           {
                a=i;
                b=k;
                flag=1;
           }
           else if(a==i&&b>k)
                b=k;
                else if(b==i)
                {
                    cout<<a<<" "<<b<<endl;
                    a=i;
                    b=k;
                }
        }
            q=q->next;
        }
    }
    cout<<a<<" "<<b<<endl;
}
int main()
{
    ALGraph g;
    while(cin>>g.vexnum>>g.arcnum)
    {
        create(g);
        CriticalActivity(g);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值