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>
const int maxn = 110;
const int INF = 100000000;
int G[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 = 0; j <= n; j++){G[i][j] = -1;}indegree[i] = 0;outdegree[i] = 0;earliest[i] = 0;latest[i] = INF;}
}int min(int a,int b){if(a < b) return a;else return b;
}int max(int a,int b){if(a > b) return a;else return b;
}int early_time(int n){int queue[n];int first = -1, rear = -1;for(int i = 1; i <= n; i++){if(indegree[i] == 0){queue[++rear] = i;}}int cnt = 0;while(first < rear){int v = queue[++first];cnt++;for(int i = 1; i <= n; i++){if(G[v][i] >= 0){indegree[i]--;earliest[i] = max(earliest[i],earliest[v] + G[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 first = -1,rear = -1;for(int i = n; i >= 1; i--){if(outdegree[i] == 0){queue[++rear] = i;latest[i] = x;}}while(first < rear){int v = queue[++first];for(int i = n; i >= 1; i--){if(G[i][v] >= 0){outdegree[i]--;latest[i] = min(latest[i],latest[v] - G[i][v]);if(outdegree[i] == 0){queue[++rear] = i;}}}}
}int main(){int n,m;scanf("%d%d",&n,&m);init(n);int u,v,w;for(int i = 1; i <= m; i++){scanf("%d%d%d",&u,&v,&w);G[u][v] = w;indegree[v]++;outdegree[u]++;}int flag;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(G[i][j] >= 0 && earliest[j] == latest[j] && (latest[j] - earliest[i] == G[i][j]))printf("%d->%d\n",i,j);}}}return 0;
}

第二个点未过,待查

#include<cstdio>
const int maxn = 110;
const int INF = 100000000;
int G[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 = 0; j <= n; j++){G[i][j] = -1;}indegree[i] = 0;outdegree[i] = 0;earliest[i] = 0;latest[i] = INF;}
}int min(int a,int b){if(a < b) return a;else return b;
}int max(int a,int b){if(a > b) return a;else return b;
}int early_time(int n){int queue[n];int first = -1, rear = -1;for(int i = 1; i <= n; i++){if(indegree[i] == 0){queue[++rear] = i;}}int cnt = 0;while(first < rear){int v = queue[++first];cnt++;for(int i = 1; i <= n; i++){if(G[v][i] >= 0){indegree[i]--;earliest[i] = max(earliest[i],earliest[v] + G[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 first = -1,rear = -1;for(int i = 1; i <= 1; i++){if(outdegree[i] == 0){queue[++rear] = i;latest[i] = x;}}while(first < rear){int v = queue[++first];for(int i = n; i >= 1; i--){if(G[i][v] >= 0){outdegree[i]--;latest[i] = min(latest[i],latest[v] - G[i][v]);if(outdegree[i] == 0){queue[++rear] = i;}}}}
}int main(){int n,m;scanf("%d%d",&n,&m);init(n);int u,v,w;for(int i = 1; i <= m; i++){scanf("%d%d%d",&u,&v,&w);G[u][v] = w;indegree[v]++;outdegree[u]++;}int flag;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(G[i][j] >= 0 && earliest[j] == latest[j] && (latest[j] - earliest[i] == G[i][j]))
//                printf("%d->%d\n",i,j);
//            }for(int j = n; j >= 1; j--){if(G[i][j] >= 0 && earliest[j] == latest[j] && (latest[j] - earliest[i] == G[i][j]))printf("%d->%d\n",i,j);}}}return 0;
}

 

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

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

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

相关文章

【Leetocde | 10 】54. 螺旋矩阵

解题代码&#xff1a; class Solution { public:vector<int> spiralOrder(vector<vector<int>>& matrix) {if (matrix.empty() || matrix[0].empty()) return {};int m matrix.size(), n matrix[0].size();vector<int> res;int up 0, down m …

09-排序1 排序 (25 分)

给定N个&#xff08;长整型范围内的&#xff09;整数&#xff0c;要求输出从小到大排序后的结果。 本题旨在测试各种不同的排序算法在各种数据情况下的表现。各组测试数据特点如下&#xff1a; 数据1&#xff1a;只有1个元素&#xff1b; 数据2&#xff1a;11个不相同的整数…

网络层

1. 简单解释一些ARP协议的工作过程

【Leetocde | 24 】152. 乘积最大子序列

这道题最直接的方法就是用DP来做&#xff0c;而且要用两个dp数组&#xff0c;其中f[i]表示子数组[0, i]范围内并且一定包含nums[i]数字的最大子数组乘积&#xff0c;g[i]表示子数组[0, i]范围内并且一定包含nums[i]数字的最小子数组乘积&#xff0c;初始化时f[0]和g[0]都初始化…

【Leetcode | 1】3. 无重复字符的最长子串

这里我们可以建立一个HashMap&#xff0c;建立每个字符和其最后出现位置之间的映射&#xff0c;然后我们需要定义两个变量res和left&#xff0c;其中res用来记录最长无重复子串的长度&#xff0c;left指向该无重复子串左边的起始位置的前一个&#xff0c;由于是前一个&#xff…

【Leetcode | 】93. 复原IP地址

class Solution { public:vector<string> strs;//用于存放临时的四个段vector<string> result;//存放结果void dfs(string &s, int beginIndex, int step) {if (step 4 && beginIndex s.size()) //搜索成功{string temRec strs[0] "." …

海量数据(一)

1. 有1亿个浮点数&#xff0c;如果找出期中最大的10000个&#xff1f; 最容易想到的方法是将数据全部排序&#xff0c;然后在排序后的集合中进行查找&#xff0c;最快的排序算法的时间复杂度一般为O&#xff08;nlogn&#xff09;&#xff0c;如快速排序。但是在32位的机器上&a…

1018 锤子剪刀布 (20 分)

大家应该都会玩“锤子剪刀布”的游戏&#xff1a;两人同时给出手势&#xff0c;胜负规则如图所示&#xff1a; 现给出两人的交锋记录&#xff0c;请统计双方的胜、平、负次数&#xff0c;并且给出双方分别出什么手势的胜算最大。 输入格式&#xff1a; 输入第 1 行给出正整数 N…

1019 数字黑洞 (20 分)

给定任一个各位数字不完全相同的 4 位正整数&#xff0c;如果我们先把 4 个数字按非递增排序&#xff0c;再按非递减排序&#xff0c;然后用第 1 个数字减第 2 个数字&#xff0c;将得到一个新的数字。一直重复这样做&#xff0c;我们很快会停在有“数字黑洞”之称的 6174&…

61. 旋转链表

给定一个链表&#xff0c;旋转链表&#xff0c;将链表每个节点向右移动 k 个位置&#xff0c;其中 k 是非负数。 示例 1: 输入: 1->2->3->4->5->NULL, k 2 输出: 4->5->1->2->3->NULL 解释: 向右旋转 1 步: 5->1->2->3->4->NULL…

1020 月饼 (25 分)

月饼是中国人在中秋佳节时吃的一种传统食品&#xff0c;不同地区有许多不同风味的月饼。现给定所有种类月饼的库存量、总售价、以及市场的最大需求量&#xff0c;请你计算可以获得的最大收益是多少。 注意&#xff1a;销售时允许取出一部分库存。样例给出的情形是这样的&#x…

2. 二叉树的深度

题目描述 输入一棵二叉树&#xff0c;求该树的深度。从根结点到叶结点依次经过的结点&#xff08;含根、叶结点&#xff09;形成树的一条路径&#xff0c;最长路径的长度为树的深度。 /* struct TreeNode {int val;struct TreeNode *left;struct TreeNode *right;TreeNode(in…

1021 个位数统计 (15 分

给定一个 k 位整数 1 (0, ,, d​k−1​​>0)&#xff0c;请编写程序统计每种不同的个位数字出现的次数。例如&#xff1a;给定 0&#xff0c;则有 2 个 0&#xff0c;3 个 1&#xff0c;和 1 个 3。 输入格式&#xff1a; 每个输入包含 1 个测试用例&#xff0c;即一个不超过…

【牛客网】X游戏

题目&#xff1a;X游戏 题目描述 我们称一个数 X 为好数, 如果它的每位数字逐个地被旋转 180 度后&#xff0c;我们仍可以得到一个有效的&#xff0c;且和 X 不同的数。要求每位数字都要被旋转。 如果一个数的每位数字被旋转以后仍然还是一个数字&#xff0c; 则这个数是有效…

1022 D进制的A+B (20 分)

输入两个非负 10 进制整数 A 和 B (≤)&#xff0c;输出 AB 的 D (1)进制数。 输入格式&#xff1a; 输入在一行中依次给出 3 个整数 A、B 和 D。 输出格式&#xff1a; 输出 AB 的 D 进制数。 输入样例&#xff1a; 123 456 8输出样例&#xff1a; 1103 #include<cstdio>…

3. 二进制中1的个数

题目描述 输入一个整数&#xff0c;输出该数二进制表示中1的个数。其中负数用补码表示。 class Solution { public:int NumberOf1(int n) {int count 0; for(int i 0; i < 32; i){if(n & (1 << i))count;}return count;} };

1023 组个最小数 (20 分)

给定数字 0-9 各若干个。你可以以任意顺序排列这些数字&#xff0c;但必须全部使用。目标是使得最后得到的数尽可能小&#xff08;注意 0 不能做首位&#xff09;。例如&#xff1a;给定两个 0&#xff0c;两个 1&#xff0c;三个 5&#xff0c;一个 8&#xff0c;我们得到的最…

C++中重载、重写(覆盖)和隐藏的区别实例分析

1.重载&#xff1a;重载从overload翻译过来&#xff0c;是指同一可访问区内被声明的几个具有不同参数列&#xff08;参数的类型&#xff0c;个数&#xff0c;顺序不同&#xff09;的同名函数&#xff0c;根据参数列表确定调用哪个函数&#xff0c;重载不关心函数返回类型。 示…

1024 科学计数法 (20 分

科学计数法是科学家用来表示很大或很小的数字的一种方便的方法&#xff0c;其满足正则表达式 [-][1-9].[0-9]E[-][0-9]&#xff0c;即数字的整数部分只有 1 位&#xff0c;小数部分至少有 1 位&#xff0c;该数字及其指数部分的正负号即使对正数也必定明确给出。 现以科学计数法…

static、const用法

一、static用法 C的static有两种用法&#xff1a;面向过程程序设计中的static和面向对象程序设计中的static。前者应用于普通变量和函数&#xff0c;不涉及类&#xff1b;后者主要说明static在类中的作用。 一、面向过程设计中的static 1、静态全局变量&#xff1a;在全局变量前…