08-图9 关键活动 (30 分)

假定一个工程项目由一组子任务构成,子任务之间有的可以并行执行,有的必须在完成了其它一些子任务后才能执行。“任务调度”包括一组子任务、以及每个子任务可以执行所依赖的子任务集。

比如完成一个专业的所有课程学习和毕业设计可以看成一个本科生要完成的一项工程,各门课程可以看成是子任务。有些课程可以同时开设,比如英语和C程序设计,它们没有必须先修哪门的约束;有些课程则不可以同时开设,因为它们有先后的依赖关系,比如C程序设计和数据结构两门课,必须先学习前者。

但是需要注意的是,对一组子任务,并不是任意的任务调度都是一个可行的方案。比如方案中存在“子任务A依赖于子任务B,子任务B依赖于子任务C,子任务C又依赖于子任务A”,那么这三个任务哪个都不能先执行,这就是一个不可行的方案。

任务调度问题中,如果还给出了完成每个子任务需要的时间,则我们可以算出完成整个工程需要的最短时间。在这些子任务中,有些任务即使推迟几天完成,也不会影响全局的工期;但是有些任务必须准时完成,否则整个项目的工期就要因此延误,这种任务就叫“关键活动”。

请编写程序判定一个给定的工程项目的任务调度是否可行;如果该调度方案可行,则计算完成整个工程项目需要的最短时间,并输出所有的关键活动。

输入格式:

输入第1行给出两个正整数N(≤100)和M,其中N是任务交接点(即衔接相互依赖的两个子任务的节点,例如:若任务2要在任务1完成后才开始,则两任务之间必有一个交接点)的数量。交接点按1N编号,M是子任务的数量,依次编号为1M。随后M行,每行给出了3个正整数,分别是该任务开始和完成涉及的交接点编号以及该任务所需的时间,整数间用空格分隔。

输出格式:

如果任务调度不可行,则输出0;否则第1行输出完成整个工程项目需要的时间,第2行开始输出所有关键活动,每个关键活动占一行,按格式“V->W”输出,其中V和W为该任务开始和完成涉及的交接点编号。关键活动输出的顺序规则是:任务开始的交接点编号小者优先,起点编号相同时,与输入时任务的顺序相反。

输入样例:

7 8
1 2 4
1 3 3
2 4 5
3 4 3
4 5 1
4 6 6
5 7 5
6 7 2

输出样例:

17
1->2
2->4
4->6
6->7

自创输入样例

16 20
1 2 6
1 3 4
1 4 5
2 5 1
3 5 1
4 6 2
6 5 0
5 7 9
5 8 7
6 8 4
7 9 2
8 9 4
10 11 4
10 12 3
11 13 5
12 13 3
13 14 1
13 15 6
14 16 5
15 16 2

输出样例

18
1->4
1->2
2->5
4->6
5->8
5->8
5->7
5->7
6->5
7->9
7->9
8->9
8->9
10->11
11->13
13->15
15->16

Note

  1. 注意有边的条件是>=0
  2. 多边的测试点始终过不了,自己测试的多变可以(将本题与递归排序那题样例结合)

Code

#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
#define MAX 100struct result{int x;int y;
}res[MAX];
int cmp(result a, result b){return a.x == b.x ? a.y > b.y : a.x < b.x;
}
int a[MAX][MAX], num, arcnum, cnt = 0, e[MAX],l[MAX],Indegree[MAX],outdegree[MAX], temp, size = 0;
void Dfs(int i){for(int j = 0; j < num; j++){if(a[i][j] >= 0 && l[j] - a[i][j] - e[i] == 0){res[size].x = i;res[size].y = j;size ++;Dfs(j);}}
}
int main() {cin >> num >>arcnum;int start;for(int i = 0; i < num; i++){       //初始化for(int j = 0; j < num; j++){a[i][j] = -1;}e[i] = 0;l[i] = MAX;Indegree[i] = outdegree[i] = 0;}for(int i = 0; i < arcnum; i++){    //输入int tempa, tempb, tempc;cin >> tempa >> tempb >> tempc;a[tempa - 1][tempb - 1] = tempc;}queue<int> q1, q2, qstart;for(int i = 0; i < num; i++){       //计算初始时的入度出度for(int j = 0; j < num; j++){if(a[j][i] >= 0) Indegree[i]++;if(a[i][j] >= 0) outdegree[i]++;}if(Indegree[i] == 0) { q1.push(i); cnt++; qstart.push(i);}if(outdegree[i] == 0){ q2.push(i); }}while(q1.size() > 0){                //拓扑排序计算e[]temp = q1.front();q1.pop();int visted = 0;for(int i = 0; i < num; i++){if(a[temp][i] >= 0){visted = 1;Indegree[i]--;if(a[temp][i] + e[temp] > e[i]) e[i] = a[temp][i] + e[temp];if(Indegree[i] == 0){q1.push(i); cnt++;}}}if(visted == 0) l[temp] = e[temp];}if(cnt != num){ cout << 0; return 0;}while(q2.size() > 0){                //反向拓扑排序计算l[]temp = q2.front();q2.pop();for(int i = 0; i < num; i++){if(a[i][temp] >= 0){outdegree[i]--;if(l[temp] - a[i][temp] < l[i]) l[i] = -a[i][temp] + l[temp];if(outdegree[i] == 0){q2.push(i);}}}}while(qstart.size() > 0){int temp = qstart.front();qstart.pop();Dfs( temp);}sort(res, res + size, cmp);sort(e, e + num);cout  <<  e[num -1] << endl;for(int i = 0; i < size; i++){cout << res[i].x + 1 << "->" << res[i].y + 1 << endl;}return 0;
}

Note2

  1. 利用栈存储拓扑序便可以直接得到逆拓扑序
  2. 用邻接矩阵邻接表存储,空间换时间
  3. 输出顺序问题只需要改一下循环的方向即可

Code2

#include<iostream>
#include<vector>
#include<queue>
#include<stack>
using namespace std;
int num,arcnum;
vector<int>adj[110]; //邻接表
int a[110][110];    //邻接矩阵
int indegree[110]={0};
int early[110]={0};
int late[110];
int main(){int i,j,temp1,temp2,temp3;scanf("%d %d",&num,&arcnum);for(i=0;i<arcnum;i++){                      //从1开始存scanf("%d %d %d",&temp1,&temp2,&temp3);indegree[temp2]++;adj[temp1].push_back(temp2);a[temp1][temp2]=a[temp2][temp1]=temp3;}queue<int>q;for(i=1;i<=num;i++){if(indegree[i]==0){q.push(i);}}int count=0;stack<int> s;while(!q.empty()){count++;int head=q.front();s.push(head); q.pop();for(i=0;i<adj[head].size();i++){int next=adj[head][i];if(early[next]<early[head]+a[head][next]){early[next]=early[head]+a[head][next];}if(--indegree[next]==0){q.push(next);}}}if(count!=num){printf("0");return 0;}printf("%d\n",early[s.top()]); for(i=1;i<=num;i++){late[i]=early[s.top()];}while(!s.empty()){int head=s.top();s.pop();for(i=0;i<adj[head].size();i++){int next=adj[head][i];if(late[head]>late[next]-a[head][next]){late[head]=late[next]-a[head][next];}}}for(i=1;i<=num;i++){for(j=adj[i].size()-1;j>=0;j--){ int next=adj[i][j];if(late[next]-early[i]-a[i][next]==0){printf("%d->%d\n",i,next);}}}
}

08-图9 关键活动 (30 分)相关推荐

  1. 数据结构 图9 关键活动

    全部每周作业和视频思考题答案和解析 见 浙江大学 数据结构 思考题+每周练习答案 题目:假定一个工程项目由一组子任务构成,子任务之间有的可以并行执行,有的必须在完成了其它一些子任务后才能执行.&quo ...

  2. 08-图9 关键活动 (30 分

    假定一个工程项目由一组子任务构成,子任务之间有的可以并行执行,有的必须在完成了其它一些子任务后才能执行."任务调度"包括一组子任务.以及每个子任务可以执行所依赖的子任务集. 比如完 ...

  3. [图] AOE网-关键路径|关键活动-原理、手算举例、C语言实现

    文章目录 AOE网 AOE的应用(AOE的相关概念) 原理:求关键活动和关键路径 求ve.vl(顶点) 求ee.el(边) 求关键路径,关键活动 手算举例 C语言实现 AOE网 [有向无环图]活动在边 ...

  4. PAT甲级1131 Subway Map (30分):[C++题解]堆优化dijkstra、单源最短路、地铁地图、巧妙地建图套dijkstra模板!!

    文章目录 题目分析 题目链接 题目分析 原题: 来源:acwing 分析: 建图:所有能走到的点之间建立一条边,比如下面一条地铁线路有4站,它们是相通的,两两之间建一条边,边权是经过的站点数. 下面考 ...

  5. 【CCCC】L3-018 森森美图 (30分),计算几何+判断三点共线+bfs最短路

    problem L3-018 森森美图 (30分) 森森最近想让自己的朋友圈熠熠生辉,所以他决定自己写个美化照片的软件,并起名为森森美图.众所周知,在合照中美化自己的面部而不美化合照者的面部是让自己占 ...

  6. 任务二:实现求平方根关键算法(30 分)求 n 以内(不包括 n)同时能被 3 和 7 整除的所有自然数之和的平方根 s,然后将结果s 输出。例如若 n 为 1000 时,则 s=153.909

    任务二:实现求平方根关键算法(30 分) 求 n 以内(不包括 n)同时能被 3 和 7 整除的所有自然数之和的平方根 s, 然后将结果 s 输出.例如若 n 为 1000 时,则 s=153.909 ...

  7. 数据结构 — 图 之 关键路径、关键活动 (文字表述)

    1.AOE网: 边表示活动的网络,边表示活动,顶点表示事件,当该事件发生了,就说明触发该事件发生的所有的活动已经完成.一个工程所需的最短时间 就是 完成从开始顶点到终止顶点的最长路径的长度. 2.关键 ...

  8. cron表达式 每天0点10分和30分_揭开考研阅卷的内幕,注意这些多得20分!

    戳上方"云逸未来"↑星标/置顶哦  六大工作组审核流程  考研统考科目实行集中统一阅卷.自命题科目试卷一般由报考院校专业导师命题,也由该院校相关院系老师阅卷:统考科目阅卷工作一般是 ...

  9. 3分和30分文章差距在哪里?

    好的分析和可视化,可以提供大量的信息,同时兼顾简洁优雅. 今天我们抛开实验设计.方法和工作量等因素,仅从文章最吸引人的图片来讨论3分和30分(顶级)文章差距在哪里? 以2017年8月25日发表在Sci ...

最新文章

  1. 地址总线是单向还是双向_碳纤维布加固为什么选择单向布?
  2. Kicad快捷键大全
  3. 广州爱立信java笔试题_爱立信笔试经历
  4. Linux下TTY与PTY的区别
  5. rocketMQ启动
  6. 嗅探软件和网络测试,新鲜!山东首条燃气嗅探犬“上岗”,通检测探漏样样精...
  7. 2021年烷基化工艺考试试卷及烷基化工艺模拟考试题
  8. MySQL 打开视图 1449_Mysql查询视图:ERROR 1449 (HY000)解决办法
  9. Python计算最大回撤、回撤天数
  10. 爬取唯美女生网站上所有小姐姐的照片
  11. 第 304 场力扣周赛
  12. cba篮球暂停次数和时间_篮球比赛一节有几次暂停?
  13. python的turtle怎么画曲线_利用 turtle库绘制简单图形
  14. 你对计算机有什么看法英语作文,关于电脑优点英语作文
  15. 【面试】TCP、UDP、Socket、HTTP网络编程面试题
  16. ITU-R BT.601 Y'CbCr
  17. 民族列表JSON(可直接复制)
  18. 量子计算机 中国科学院,中科院量子计算机取得重大突破
  19. 微信小程序跨域问题 post 403 Invalid CORS request 后台
  20. 053试题 193 - recover 命令

热门文章

  1. 买鸡卖鸡问题个人分析
  2. STM32H7 ADC偏移校准以及线性度校准
  3. Python二维列表数组list的初始化与赋值
  4. 苹果推出了AI手机,打造一款高度个性化的设备
  5. 2020年B证(安全员)模拟考试及B证(安全员)证考试
  6. 容联云被启动退市:因无法发出年报 曾市值达77亿美元
  7. 算法-贝尔曼-福特算法
  8. 集群环境ssh免密码登录设置
  9. 技嘉H370 HD3主板的物理机上安装 Linux CentOS7 解决无网卡驱动
  10. 如何制作gif图片?这几个方法分享给你