AOE关键路径
2016-08-25 13:38
337 查看
AOE网上的关键路径
Time Limit: 1000ms Memory limit: 65536K 有疑问?点这里^_^
题目描述
一个无环的有向图称为无环图(DirectedAcyclic Graph),简称DAG图。
AOE(Activity
On Edge)网:顾名思义,用边表示活动的网,当然它也是DAG。与AOV不同,活动都表示在了边上,如下图所示:
如上所示,共有11项活动(11条边),9个事件(9个顶点)。整个工程只有一个开始点和一个完成点。即只有一个入度为零的点(源点)和只有一个出度为零的点(汇点)。
关键路径:是从开始点到完成点的最长路径的长度。路径的长度是边上活动耗费的时间。如上图所示,1 到2 到 5到7到9是关键路径(关键路径不止一条,请输出字典序最小的),权值的和为18。
输入
这里有多组数据,保证不超过10组,保证只有一个源点和汇点。输入一个顶点数n(2<=n<=10000),边数m(1<=m<=50000),接下来m行,输入起点sv,终点ev,权值w(1<=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>
# define MAXN 10010 //最大顶点数
# define MAXM 50010 //最大边数
using namespace std;
struct node
{
int d; //<u,v>之间的距离
int to; //v点
int on;//活动序号
struct node*next;
};
typedef struct node Node;
struct node *ls1[MAXN]; //正向存储图的信息,出边表的表头
struct node *ls2[MAXN]; //逆向存储图的信息,入边表的表头
int Ee[MAXN]; //各事件最早可能开始的时间
int El[MAXN];//各事件的最迟允许开始时间
int e[MAXN]; //各活动最早可能开始的时间等于Ee
int l[MAXN]; //各活动的最迟允许开始时间
int cnt1[MAXN];//统计正向的各个点的入度
int cnt2[MAXN];//统计反向的各个点的出度
int n,m; //n 顶点数 m 边数
void O_TopSort() //正向拓扑求Ee,可以认为是单点求最长路径
{
int i,u,v;
Node*p;
memset(Ee,0,sizeof(Ee));
stack<int>s;
for(i=1;i<=n;i++)
{
if(cnt1[i] == 0)//入度为0的点入栈
s.push(i);
}
while(!s.empty())
{
u = s.top();
s.pop();
p = ls1[u]; //找到从u发出的每条边,将终点v度数减去1
while(p)
{
v = p->to;
cnt1[v]--;
if(cnt1[v] == 0)
s.push(v);
if(Ee[u] + p->d > Ee[v])
Ee[v] = Ee[u] + p->d;
p = p->next;
}
}
}
void R_TopSort() //逆序拓扑
{
int i,u,v;
Node*p;
memset(El,0,sizeof(El));
stack<int> s;
for(i=1;i<=n;i++)
{
El[i] = Ee
;
if(cnt2[i] == 0)
s.push(i);
}
while(!s.empty())
{
u = s.top();
s.pop();
p = ls2[u];
while(p)
{
v = p->to;
if(--cnt2[v] == 0)
s.push(v);
if(El[u] - p->d < El[v])
El[v] = El[u] - p->d;
p = p->next;
}
}
}
int main()
{
int i,u,v,w;
Node*p;
Node*q;
while(cin>>n>>m)
{
memset(cnt1,0,sizeof(cnt1));
memset(cnt2,0,sizeof(cnt2));
for(i=1;i<=n;i++)
{
ls1[i] = NULL;
ls2[i] = NULL;
}
for(i=0;i<m;i++)//输入m条边的信息
{
cin>>u>>v>>w;
/*出边表*/
p = new Node;
p->d = w;
p->to = v;
p->on = i;
cnt1[v]++;
p->next = ls1[u];
ls1[u] = p;
/*入边表*/
q = new Node;
q->d = w;
q->to = u;
q->on = i;
cnt2[u]++;
q->next = ls2[v];
ls2[v] = q;
}
O_TopSort();//源点到汇点的最长距离
cout<<Ee
<<endl;
R_TopSort();
int k,j;
int Min;
int flag;
for(i=1;i<=n;i++)
{
p = ls1[i];
flag = 0;
if(p)
Min = p->to;
while(p)
{
j = p->to;
k = p->on;//取出改点编号
e[k] = Ee[i]; //边<i,j>
l[k] = El[j] - p->d;
if(e[k] == l[k])//为关键活动
{
if(Min > j)
{
Min = j;
}
flag = 1;
}
p = p->next;
}
if(flag)
{
cout<<i<<" "<<Min<<endl;
i = Min - 1;//直接跳转到当前关键路径节点的下一节点
ls1[i] = NULL;//将字典序最小的赋值
}
}
}
return 0;
}
相关文章推荐
- 数据结构实验之图论十一:AOE网上的关键路径
- AOE图的关键路径
- AOE网上的关键路径
- sdut2498--AOE网上的关键路径(spfa+最小字典序)
- AOE网上的关键路径
- AOE求关键路径
- SDUT 2498 AOE网上的关键路径
- AOE网上的关键路径(spfa+按字典序输出最长路)
- 关键路径_AOE_基于邻接表
- 拓扑排序与AOE图关键路径
- AOE网络,最长路关键路径的学习
- AOE网上的关键路径
- AOE网上的关键路径(拓扑排序+SPFA算法)
- AOE网上的关键路径
- 数据结构 学习笔记(九):图(下):最小生成树(Prim,Kruskal 算法),拓扑排序 AOV,关键路径 AOE
- AOE网上的关键路径
- 数据结构实验之图论十一:AOE网上的关键路径
- 数据结构实验之图论十一:AOE网上的关键路径
- 数据结构实验之图论十一:AOE网上的关键路径
- 数据结构实验之图论十一:AOE网上的关键路径