AOE网上的关键路径
Time Limit: 1000MS
Memory Limit: 65536KB
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
关键路径的权值和,并且从源点输出关键路径上的路径(如果有多条,请输出字典序最小的)。
Example 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
Example Output
18 1 2 2 5 5 7 7 9
//逆向建图解决按字典序输出
#include<stdio.h> #include<string.h> #include<queue> #define maxn 200001 #define INF 0x3f3f3f3f using namespace std; struct node { int v,w,next; } s[maxn]; int m,n,cnt; int dis[maxn],vis[maxn],pre[maxn],head[maxn]; void add(int u,int v,int w) { s[cnt].v=v; s[cnt].w=w; s[cnt].next=head[u]; head[u]=cnt++; } void spfa(int ss,int ee) { queue<int>q; for(int i=1; i<=n; i++) { dis[i]=-INF; } dis[ss]=0; vis[ss]=1; q.push(ss); while(!q.empty()) { int u=q.front(); q.pop(); vis[u]=0; for(int i=head[u]; i!=-1; i=s[i].next) { int v=s[i].v,w=s[i].w; if(dis[v]<dis[u]+w||(dis[v]==dis[u]+w&&pre[v]>u)) { pre[v]=u; dis[v]=dis[u]+w; //printf("%d\n",dis[v]); if(!vis[v]) { vis[v]=1; q.push(v); } } } } printf("%d\n",dis[ee]); int t=ee; while(t!=ss) { printf("%d %d\n",t,pre[t]); t=pre[t]; } } int main() { while(~scanf("%d%d",&n,&m)) { int i,j; int in[maxn],out[maxn]; cnt=0; memset(in,0,sizeof(in)); memset(out,0,sizeof(out)); memset(head,-1,sizeof(head)); memset(vis,0,sizeof(vis)); memset(pre,-1,sizeof(pre)); for(i=0; i<m; i++) { int u,v,w; scanf("%d%d%d",&u,&v,&w); add(v,u,w); in[u]++; out[v]++; } int ss,ee; for(i=1; i<=n; i++) { if(!in[i]) ss=i; if(!out[i]) ee=i; } spfa(ss,ee); } }

本文介绍了一种求解AOE网(活动在边上的网)中关键路径的方法。通过给出具体的实例,详细解释了如何确定项目的最长时间线及其构成路径。文章提供了完整的C++实现代码,帮助读者理解算法原理。
236

被折叠的 条评论
为什么被折叠?



