PAT 关键活动 拓扑排序-关键路径

链接:

关键活动

思路:

1、首先通过队列加邻接表完成拓扑排序:

所有入度为0的节点a入队

在邻接表中找到a的所有后继节点

后继节点入度-1

如果后继节点入度为0

则后继节点入队

2、当图中出现环时则任务调度不可行:

只要判断是否入队n次即可

3、在拓扑排序的过程中用path数组保存所有(关键活动)的前驱节点

最后通过队列和path数组

从最终活动依次往前遍历 保存出现的所有边

排序输出即可

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<vector>
#include<algorithm>
using namespace std;
struct node{
    int to;
    int w;
};
struct A{               //构建结构体保存关键路径的所有边 方便排序
   int a,b;
}edge[4999];

vector<node>w[105];     //邻接表
vector<int>path[105];   //保存每个点关键活动的所有前驱节点

int last[105];          //保存最晚完成的时间
int degree[105];        //保存每个点的入度

int n;
int cmp(A aa,A bb){
    return aa.a<bb.a;
}
void print(int loc)          //通过队列保存关键路径的所有边
{
    int s=0;
    queue<int>qq;
    int vis[105],head,i;
    memset(vis,0,sizeof(vis));
    qq.push(loc);
    while(!qq.empty()){
        head=qq.front();
        qq.pop();
        for(i=path[head].size()-1;i>=0;i--){
            loc=path[head][i];
            edge[s].a=loc;
            edge[s++].b=head;
            if(!vis[loc]){
                vis[loc]=1;
                qq.push(loc);
            }
        }
    }
    sort(edge,edge+s,cmp);
    for(int i=0;i<s;i++)
        cout<<edge[i].a<<"->"<<edge[i].b<<endl;
}
void top_sort()                  //队列实现拓扑排序
{
    int i,head,loc,s=0,ans=0,ans_loc;
    queue<int>q;

    for(i=1; i<=n; i++)
        if(degree[i]==0)
            q.push(i);

    while(!q.empty())
    {

        head=q.front();
        s++;                   //n个节点全部入队才完成拓扑排序  否则构成环
        ans=last[head];
        ans_loc=head;          //最后进队的是最终的活动
        q.pop();

        for(i=0; i<w[head].size(); i++)
        {
            loc=w[head][i].to;
            if(last[head]+w[head][i].w>last[loc])    //如果这条路径花费时间更长
            {
                path[loc].clear();                   //之前保存的前驱关键活动清空
                last[loc]=last[head]+w[head][i].w;
                path[loc].push_back(head);           //添加当前的前驱关键活动
            }
            else if(last[head]+w[head][i].w==last[loc])
            {
                path[loc].push_back(head);           //花费时间相同-添加
            }
            degree[loc]--;
            if(!degree[loc])
                q.push(loc);
        }
    }
    if(s==n)
        cout<<ans<<endl;
    else
    {
        cout<<0<<endl;
        return;
    }
    print(ans_loc);      //从最后的关键活动开始找出所有边
    return;
}
int main()
{
    int m,i,j;
    int a,b,weight;
    scanf("%d%d",&n,&m);
    for(i=1; i<=n; i++){
        degree[i]=0;
        last[i]=0;
    }
    while(m--)
    {
        scanf("%d%d%d",&a,&b,&weight);
        w[a].push_back((node){b,weight});
        degree[b]++;
    }
    top_sort();
    return 0;
}
时间: 2024-10-08 14:41:58

PAT 关键活动 拓扑排序-关键路径的相关文章

HDU4109 Instrction Arrangement 拓扑排序 关键路径

Problem Description Ali has taken the Computer Organization and Architecture course this term. He learned that there may be dependence between instructions, like WAR (write after read), WAW, RAW. If the distance between two instructions is less than

06-5. 关键活动(30) 关键路径 和输出关键路径

06-5. 关键活动(30) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 本实验项目是实验项目6-06的深化.任务调度问题中,如果还给出了完成每个子任务需要的时间,则我们可以算出完成整个工程需要的最短时间.在这些子任务中,有些任务即使推迟几天完成,也不会影响全局的工期:但是有些任务必须准时完成,否则整个项目的工期就要因此延误,这种任务就叫"关键活动". 请编写程序判定一个给定的工程项目的任务调度是否可行:如果该调度方案可行

拓扑排序之关键路径(深度优先搜索)

/* Name: 拓扑排序之关键路径(深度优先搜索) Copyright: Author: 巧若拙 Date: 17-11-14 21:02 Description: 拓扑排序之关键路径 若在带权的有向图中,以顶点表示事件,以有向边表示活动,边上的权值表示活动的开销(如该活动持续时间), 则此带权的有向图称为边表示活动的网 (Activity on Edge Network) ,简称 AOE 网. (1)AOV 网具有的性质 ⒈ 只有在某顶点所代表的事件发生后,从该顶点出发的各有向边所代表的活动

[从今天开始修炼数据结构]无环图的应用 —— 拓扑排序和关键路径算法

上一篇文章我们学习了最短路径的两个算法.它们是有环图的应用.下面我们来谈谈无环图的应用. 一.拓扑排序 博主大学学的是土木工程,在老本行,施工时很关键的节约人力时间成本的一项就是流水施工,钢筋没绑完,浇筑水泥的那帮兄弟就得在那等着,所以安排好流水施工,让工作周期能很好地衔接就很关键.这样的工程活动,抽象成图的话是无环的有向图. 在表示工程的有向图中,用顶点表示活动,弧表示活动之间的优先关系,这样的有向图为顶点表示活动的网,成为AOV网(Active On Vertex Network) ※ 若在

图的拓扑排序、关键路径、最短路径算法 -- C++实现

一:拓扑排序 对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若边(u,v)∈E(G),则u在线性序列中出现在v之前.通常,这样的线性序列称为满足拓扑次序(Topological Order)的序列,简称拓扑序列. 拓扑排序就是要找到入度为0的顶点,并依次压栈.首先将栈顶顶点输出,删除以此顶点为弧尾的顶点,并更新其他顶点的入度.若入度为0,则继续压栈.更新完毕继续出栈,直至栈空.元素出栈并输出

hdu Instrction Arrangement(关键路径 + 拓扑排序)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2586 题意: 5 2                     //5个进程(编号从 0 开始)需要被执行,有2个约束条件, 问全部执行完成的最短时间. 1 2 1                   //1号要在2号进程执行完成的后一纳秒执行 3 4 1 Sample Output 2 关键路径: 基于AOE网(Activity On Edge),也就是说,每一条边代表着一个事件的发生,边的权值即为

DAG的运用:拓扑排序(AOV),关键路径(AOE)与dp的关系

dp在DAG中有两个运用,一个是固定终点和起点的最长路(最短路) 其中最长路的算法就是关键路径(AOE)的算法. 下面是代码 #include<cstdio> #include<algorithm> #define maxn 2001 using namespace std; int a[10],head[maxn],n,p,f[maxn],tp[maxn],de[maxn],ds[maxn]; struct ss { int to,w,last; }x[maxn*1000]; v

PAT Advanced 1146 Topological Order (25) [拓扑排序]

题目 This is a problem given in the Graduate Entrance Exam in 2018: Which of the following is NOT a topological order obtained from the given directed graph? Now you are supposed to write a program to test each of the options. Input Specification: Each

数据结构 - 拓扑排序

应用背景 学生选修课程问题 顶点--表示课程 有向弧--表示先决条件,若课程i是课程j的先决条件,则图中有弧(i,j) 学生应按怎样的顺序学习这些课程,才能无矛盾.顺利地完成学业--拓扑排序 拓扑序列是有向无环图中各顶点构成的有序序列.该序列满足如下条件:如果图中一顶点vi到另一顶点vj存在一条路径,那么vj在此图的拓扑排序序列中位于vi之后. 有向无环图(DAG)和 AOV网 有向无环图"(Directed Acyclic Graph,简称DAG AOV网 (Activity On Verte