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

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

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

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

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

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

输入格式:

输入第1行给出两个正整数N(≤)和M,其中N是任务交接点(即衔接相互依赖的两个子任务的节点,例如:若任务2要在任务1完成后才开始,则两任务之间必有一个交接点)的数量。交接点按1~N编号,M是子任务的数量,依次编号为1~M。随后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
#include<cstdio>
#include<cstring>
const int maxn = 110;
const int INF = 100000000;int map[maxn][maxn];
int indegree[maxn],outdegree[maxn];
int earliest[maxn],latest[maxn];void init(int n){for(int i = 1; i <= n; i++){for(int j = 1; j <= n; j++){map[i][j] = -1;}indegree[i] = 0;outdegree[i] = 0;earliest[i] = 0;latest[i] = INF;}
}int max(int a,int b){return a > b ? a : b;
}int min(int a,int b){return a < b ? a : b;
}int early_time(int n){int queue[n];int front = -1, rear = -1;for(int i = 1; i <= n; i++){if(indegree[i] == 0){queue[++rear] = i;}}int cnt = 0;while(front < rear){int v = queue[++front];cnt++;for(int i = 1; i <= n; i++){if(map[v][i] >= 0){indegree[i]--;earliest[i] = max(earliest[i],earliest[v]+map[v][i]);if(indegree[i] == 0){queue[++rear] = i;}}}}int ans = 0;if(cnt != n) ans = -1;else{ans = earliest[0];for(int i = 1; i <= n; i++){if(ans < earliest[i]) ans = earliest[i];}}return ans;
}void late_time(int n,int x){int queue[n];int front = -1,rear = -1;for(int i = n; i >= 1; i--){if(outdegree[i] == 0){queue[++rear] = i;latest[i] = x;}}while(front < rear){int v = queue[++front];for(int i = n; i >= 1; i--){if(map[i][v] >= 0){outdegree[i]--;latest[i] = min(latest[i],latest[v]-map[i][v]);if(outdegree[i] == 0){queue[++rear] = i;}}}}
}int main(){int n,m;scanf("%d%d",&n,&m);init(n);int v,u,w;for(int i = 0; i < m; i++){scanf("%d%d%d",&u,&v,&w);map[u][v] = w;indegree[v]++;outdegree[u]++;}int flag = early_time(n);if(flag == -1) printf("0\n");else{printf("%d\n",flag);late_time(n,flag);for(int i = 1; i <= n; i++){if(earliest[i] != latest[i]) continue;for(int j = n; j >= 1; j--){if(map[i][j] >= 0 && earliest[j] == latest[j] && (latest[j] - earliest[i] == map[i][j]))printf("%d->%d\n",i,j); }}}return 0;
}

 

转载于:https://www.cnblogs.com/wanghao-boke/p/10901852.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/385067.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++ Primer

C Primer目录索引 虚函数表剖析&#xff08;一&#xff09;虚函数表剖析&#xff08;二&#xff09;static关键字用法 volatile、const的用法​​​​​​​

10-排序4 统计工龄 (20 分)

给定公司N名员工的工龄&#xff0c;要求按工龄增序输出每个工龄段有多少员工。 输入格式: 输入首先给出正整数N&#xff08;≤&#xff09;&#xff0c;即员工总人数&#xff1b;随后给出N个整数&#xff0c;即每个员工的工龄&#xff0c;范围在[0, 50]。 输出格式: 按工龄的递…

10-排序6 Sort with Swap(0, i) (25 分)

Given any permutation of the numbers {0, 1, 2,..., N−1}, it is easy to sort them in increasing order. But what if Swap(0, *) is the ONLY operation that is allowed to use? For example, to sort {4, 0, 2, 1, 3} we may apply the swap operations in the follow…

Java读取Excel文件

首先下载jxl.jar包&#xff0c;下载地址&#xff1a;http://download.csdn.net/detail/prstaxy/4469935然后在工程文件上右键选Built Path—Configure Built Path切换到Libraries导入jxl.jar包。读取Excel方法示例&#xff1a;写入Excel见文章&#xff1a;http://blog.csdn.net…

11-散列1 电话聊天狂人 (25 分)

给定大量手机用户通话记录&#xff0c;找出其中通话次数最多的聊天狂人。 输入格式: 输入首先给出正整数N&#xff08;≤&#xff09;&#xff0c;为通话记录条数。随后N行&#xff0c;每行给出一条通话记录。简单起见&#xff0c;这里只列出拨出方和接收方的11位数字构成的手机…

Java写入Excel文件

首先下载jxl.jar包&#xff0c;下载地址&#xff1a;http://download.csdn.net/detail/prstaxy/4469935然后在工程文件上右键选Built Path—Configure Built Path切换到Libraries导入jxl.jar包。写入Excel方法示例&#xff1a;读取Excel见文章&#xff1a;http://blog.csdn.net…

Glib介绍

GLib是一种底层库&#xff0c;创建GDK和GTK应用程序时该库提供许多有用的定义和函数。包括基本类型及限制的定义、标准宏、类型转化、字节序、存储分配、警告和断言、消息记录、计时器、字符串工具、hook函数、句法扫描器、动态加载模块和字符串自动补全&#xff0c;同时也提供…

11-散列3 QQ帐户的申请与登陆 (25 分)

实现QQ新帐户申请和老帐户登陆的简化版功能。最大挑战是&#xff1a;据说现在的QQ号码已经有10位数了。 输入格式: 输入首先给出一个正整数N&#xff08;≤&#xff09;&#xff0c;随后给出N行指令。每行指令的格式为&#xff1a;“命令符&#xff08;空格&#xff09;QQ号码&…

glib字符串

学过面向对象语言的同学一定都知道String类&#xff0c;一定知道这个类对字符串的操作是多麽的方便&#xff0c;但是c语言中是没有这个类&#xff0c;甚至没有类的概念&#xff0c;但是glib帮我们做的这个“类” GString 除了使用gchar *进行字符串处理以外&#xff0c;Glib还…

KMP 串的模式匹配 (25 分)

给定两个由英文字母组成的字符串 String 和 Pattern&#xff0c;要求找到 Pattern 在 String 中第一次出现的位置&#xff0c;并将此位置后的 String 的子串输出。如果找不到&#xff0c;则输出“Not Found”。 本题旨在测试各种不同的匹配算法在各种数据情况下的表现。各组测试…

命令行工具tshark使用小记

1、目的 写这篇博客的目的主要是为了方便查阅&#xff0c;使用wireshark可以分析数据包&#xff0c;可以通过编辑过滤表达式来达到对数据的分析&#xff1b;但我的需求是&#xff0c;怎么样把Data部分导出来&#xff0c;因为后续的工作主要针对数据包的Data部分&#xff0c;主要…

winshark重要数据结构

说起来有一些惭愧&#xff0c;研究wireshark有一段时间了&#xff0c;但是对源代码的分析却至今没有什么进展。。。 最初想要研究wireshark是因为我的开题是基于wireshark来做的。 现在有很多抓包工具&#xff0c;wireshark的优势在于完全开源&#xff0c;分析功能强大&#xf…

C语言写数据库(二)

简单的实现增删查改的操作后&#xff0c;实现了一个先读写其中一个表的某两项内容&#xff0c;再把相关字符段写入到另外一张表中去。涉及到查询和插入两个步骤。 其中还涉及到汉字的读写和插入&#xff0c;会有字符的操作产生乱码。所以要先保证mysql的汉字字符编码&#xff0…

wireshark源代码分析

各位亲&#xff0c;不是我不想回复你们的问题。是我也不了解。不能误导。希望大家相互帮助。看看能否帮那些提问的小盆友们回复一下呢&#xff1f; 这些都是转载的&#xff0c;如果实在没有办法&#xff0c;可以打开链接到原作者哪里去提问试试看。。。 经过多次尝试&#xf…

C语言写数据库(三)

遇到的问题以及解决思路方法 1.外部导入数据库文件 进入mysql&#xff0c;创建数据库sh_robot source /home/exbot/sh_robot.sql 查看数据库编码格式 show variables like “%char%”; 2.数据库插入操作 进入相关数据库&#xff1a;use 数据库名&#xff1b; 查询存在该表是否存…

Makefile(一)

在一个文件夹中建一个c文件 //main.c #include<stdio.h> int main() {printf("version 1.0");return 0; } 在当前目录下编写makefile文件 //makefile: test : main.o //一种依赖关系声明&#xff0c;生成test可执行程序需要以来main.o文件gcc -o test main.…

Defunct进程 僵尸进程

在测试基于 DirectFBGstreamer 的视频联播系统的一个 Demo 的时候&#xff0c;其中大量使用 system 调用的语句&#xff0c;例如在 menu 代码中的 system("./play") &#xff0c;而且多次执行&#xff0c;这种情况下&#xff0c;在 ps -ef 列表中出现了大量的 defunc…

make文件基础用法

参照&#xff1a;https://www.jianshu.com/p/0b2a7cb9a469 创建工作目录&#xff0c;包含一下文件 main.cperson.cb.hc.h/*** c.h ***/ //this is c.h /*** b.h ***/ //this is b.h /*** main.c ***/ #include<stdio.h> //#include"a1.h" //#include"b.h&…

一个Linux下C线程池的实现(转)

1.线程池基本原理 在传统服务器结构中, 常是 有一个总的 监听线程监听有没有新的用户连接服务器, 每当有一个新的 用户进入, 服务器就开启一个新的线程用户处理这 个用户的数据包。这个线程只服务于这个用户 , 当 用户与服务器端关闭连接以后, 服务器端销毁这个线程。然而频繁地…

二维数组作为函数参数

#include<stdio.h> //#include<> //二位数组作为函数参数时&#xff0c;可以不指定第一个下标 void print_buf(int (*p)[3],int a,int b) //void print_buf(int p[][3],int a,int b) {int i,j;for(i 0 ; i < a; i){for(j 0; j < b; j){printf("p[%…