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.pswp.cn/news/385254.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/385254.shtml
英文地址,請注明出處:http://en.pswp.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;在全局變量前…