您的位置:首页 > 理论基础 > 数据结构算法

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

2017-12-02 16:49 369 查看
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

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

关键路径的解释:

http://blog.163.com/zhoumhan_0351/blog/static/3995422720098236028304/

轻松计算关键路径的方法:(一步一步的)

http://blog.csdn.net/wang379275614/article/details/13990163

#include <iostream>
#include <cstring>
using namespace std;
struct node
{
int a, b, c;

}edge[50010];
int path[50010], dis[50010], in[50010], out[50010];
//path[i] 存放第i个点的下一个点;dis[i]存放从i点到汇点的最大路径
//所以dis[start]存放着关键路径的权值和
int start;//标记起点
void bellman(int n, int m)
{
memset(path, 0, sizeof(path));
memset(dis, 0, sizeof(dis));
for(int i = 2; i <= n; i++)//n个顶点,更新n-1次
{
int flag = 0;//标记是否所有的点更新完了
//动态规划求解,不断更新dis[i]值,直到dis[i]最大,停止更新
//所有的点的dis都是最大时,停止更新,flag = 0, 退出
for(int j = 1; j <= m; j++)
{
if(dis[edge[j].a] < dis[edge[j].b] + edge[j].c || (dis[edge[j].a] == dis[edge[j].b] + edge[j].c && edge[j].b < path[edge[j].a]))
{
dis[edge[j].a] = dis[edge[j].b] + edge[j].c;
path[edge[j].a] = edge[j].b;
flag = 1;
}
}
if(flag == 0)
break;
}
cout<<dis[start]<<endl;
int k = start;
while(path[k] != 0)
{
cout<<k<<" "<<path[k]<<endl;
k = path[k];
}
}
int main()
{
int n, m, a, b, c;
while(cin>>n>>m)
{
memset(edge, 0, sizeof(edge));
memset(in, 0, sizeof(in));
memset(out, 0, sizeof(out));
for(int i = 1; i <= m; i++)
{
cin>>a>>b>>c;
edge[i].a = a;
edge[i].b = b;
edge[i].c = c;
in[a]++;//入点
out[b]++;//出点
}
for(int i = 1; i <= n; i++)
{
if(out[i] == 0)//把出度为0的点(汇点)当做起点
start = i;
}
bellman(n, m);
}
return 0;
}


#include <iostream>
#include <cstring>
using namespace std;
#define INF 0x3f3f3f
struct node
{
int a, b, c;
}edge[50010];
int in[50010];
int n, start;
int flag;
void bellman(int n, int m)
{
int path[50010], dis[50010];
memset(path, 0, sizeof(path));
memset(dis, 0, sizeof(dis));
int i, j;
for(i = 1; i <= n; i++)
{
flag = 0;
for(j = 1; j<=m; j++)
{
if(dis[edge[j].a] < dis[edge[j].b] +edge[j].c || (dis[edge[j].a] == dis[edge[j].b] +edge[j].c && edge[j].b < path[edge[j].a]))
{
dis[edge[j].a] = dis[edge[j].b] +edge[j].c;
path[edge[j].a] = edge[j].b;
flag = 1;
}
}
if(flag== 0)
{
break;
}
}
cout<<dis[start]<<endl;
int k = start;
while(path[k] != 0)
{
cout<<k<<" "<<path[k]<<endl;
k = path[k];
}

}
int main()
{
int m, a, b, c;
while(cin>>n>>m)
{
memset(edge, 0, sizeof(edge));
memset(in, 0, sizeof(in));
for(int i =1; i<=m;i++)
{
cin>>a>>b>>c;
edge[i].a = a;
edge[i].b = b;
edge[i].c = c;
in[b]++;
}
for(int i = 1; i <= n; i++)
{
if(in[i] == 0)
{
start= i;
}
}
bellman(n,m);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: