SDUT 2498 数据结构实验之图论十一:AOE网上的关键路径

 

数据结构实验之图论十一:AOE网上的关键路径

Time Limit: 2000 ms Memory Limit: 65536 KiB

Problem Description

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

Input

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

Output

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

Sample Input

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

Sample Output

18
1 2
2 5
5 7
7 9

提示:该题的知识点是AOE关键路径,而AOE关键路径的特点就是不管是从前往后找还是从后往前更新,结点的权值都是不变一条路径。

代码实现如下(g++):
#include<bits/stdc++.h>
#define N 500500

using namespace std;

struct node
{
    int va,vb,w;
} dian[N];

int path[N],dut[N],in[N],out[N],ans;

void AOE(int n,int m)//AOE关键路径就是找从前往后更新的各点权值和从后往前更新的各点权值一样的点的路径即为关键路径
{
    memset(path,0,sizeof(path));
    memset(dut,0,sizeof(dut));
    for(int j=2; j<=n; j++)
    {
        int temp=0;
        for(int i=1; i<=m; i++)
        {
            if((dut[dian[i].va]<dut[dian[i].vb]+dian[i].w)||(dut[dian[i].va]==dut[dian[i].vb]+dian[i].w&&dian[i].vb<path[dian[i].va]))//不断更新各结点的权值
            {
                dut[dian[i].va]=dut[dian[i].vb]+dian[i].w;//找到各结点权值最大的一条路
                path[dian[i].va]=dian[i].vb;//记录下从前边点到的后边点的路径
                temp=1;
            }
        }
        if(!temp)
            break;
    }
    printf("%d\n",dut[ans]);
    int k=ans;
    while(path[k]!=0)
    {
        printf("%d %d\n",k,path[k]);
        k=path[k];
    }
}



int main()
{
    int n,m,i,a,b,c;
    while(~scanf("%d %d",&n,&m))
    {
        memset(dian, 0, sizeof(dian));
        memset(in, 0, sizeof(in));
        memset(out, 0, sizeof(out));
        for(i=1; i<=m; i++)
        {
            scanf("%d %d %d",&a,&b,&c);
            dian[i].va=a;
            dian[i].vb=b;
            dian[i].w=c;
            in[a]++;
            out[b]++;
        }
        for(i=1; i<=n; i++)
        {
            if(out[i]==0)
            {
                ans=i;//记录最后一个点的位置
            }
        }
        AOE(n,m);
    }
    return 0;
}


/***************************************************
Result: Accepted
Take time: 796ms
Take Memory: 1640KB
****************************************************/

猜你喜欢

转载自www.cnblogs.com/jkxsz2333/p/9508002.html
今日推荐