数据结构 08-图8 How Long Does It Take (25 分)
Posted keiiha
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构 08-图8 How Long Does It Take (25 分)相关的知识,希望对你有一定的参考价值。
Given the relations of all the activities of a project, you are supposed to find the earliest completion time of the project.
Input Specification:
Each input file contains one test case. Each case starts with a line containing two positive integers N (≤100), the number of activity check points (hence it is assumed that the check points are numbered from 0 to N−1), and M, the number of activities. Then M lines follow, each gives the description of an activity. For the i
-th activity, three non-negative numbers are given: S[i]
, E[i]
, and L[i]
, where S[i]
is the index of the starting check point, E[i]
of the ending check point, and L[i]
the lasting time of the activity. The numbers in a line are separated by a space.
Output Specification:
For each test case, if the scheduling is possible, print in a line its earliest completion time; or simply output "Impossible".
Sample Input 1:
9 12
0 1 6
0 2 4
0 3 5
1 4 1
2 4 1
3 5 2
5 4 0
4 6 9
4 7 7
5 7 4
6 8 2
7 8 4
Sample Output 1:
18
Sample Input 2:
4 5
0 1 1
0 2 2
2 1 3
1 3 4
3 2 5
Sample Output 2:
Impossible
核心思路 用拓扑算法检测图中是否有环存在,如果存在环则输出"Impossible" , 如果是有向无环图DAG(Directed Acyclic Graph) 则输出关键路径的总权值
在进行拓扑排序输出的时候, 可以一同完成 活动时间的计算 和 关键路径的标记
拓扑算法核心
bool toplogicalSort(){ //toplogicSort检查DAG有向无环图(Directed Acyclic Graph)是否存在环 int count{0};//记录拓扑排序序列中的结点数量 vector<int> queue(0); int temp; vector<int> visited(size); for(int i=0;i<size;i++){//入度为0的结点入栈 if(!events[i]->indegree){ queue.push_back(i); count++; visited[i]=1; } } while(!queue.empty()){//栈不为空时说明有入度为0的结点存在 temp=queue.front(); queue.erase(queue.begin()); for(int i=0;i<size;i++){ if(!visited[i]&&vertexs[temp][i]<9999){//将所有入度为temp的结点 入度-1 if(!(--events[i]->indegree)){//如果入度为0则加入队列 visited[i]=1; queue.push_back(i); count++; } } } } //如果count不等于events.size()说明存在环 }
在拓扑排序过程中, 如果一个结点 j 入度为0 需要入队进行迭代
与此同时 结点 i 的前继任务全部完成, 此时对结点 i 的前继任务进行遍历可以算出到结点 j 的关键路径和关键路径长度,
寻找( i 的前继结点 j 最早开始时间 + 前继结点 j 到结点 i ) 的最大值 (es是early start的缩写) , 这个所需时间最大值的 前继结点 同时也是结点i的关键路径结点
vertexs[j][i]中存的是有向图 由 j 到 i 的长度
for(int j=0;j<size;j++){//找出这个入度为0的结点中 前继结点到这个点的最大时间 if(vertexs[j][i]<9999 && visited[j] && events[j]->es + vertexs[j][i]> events[i]->es){ events[i]->es = events[j]->es + vertexs[j][i]; events[i]->keyEvent=j;//哪个结点到这个结点耗时最多 这个结点就是当前结点的关键路径 } }
#include <iostream> #include <vector> using namespace std; //计算关键路径长度 class event{ public: int es{0};//最早发生时间 int ef{0};//最晚发生时间 int ls{9999};//最晚开始时间 int lf{9999};//最晚结束时间 int indegree{0};//入度 int outgegree{0};//出度 int keyEvent{-1}; }; class matricGraphic{ public: vector<event*> events; vector<vector<int>> vertexs; matricGraphic()=default; int size; void build(int n,int m){ int a,b; size=n; for(int i=0;i<n;i++){ event* newevent=new event; events.push_back(newevent); } vertexs=vector<vector<int>>(n,vector<int>(n,9999));//初始值为9999 for(int i=0;i<m;i++){ scanf("%d %d",&a,&b); scanf("%d",&vertexs[a][b]); events[a]->outgegree++;//a的出度++ events[b]->indegree++;//b的入度++ } } bool toplogicalSort(){ //toplogicSort检查DAG有向无环图(Directed Acyclic Graph)是否存在环 //栈中存的是入度为0的点 但是本题中默认只有起点0是入度为0 int count{0};//记录拓扑排序序列中的结点数量 vector<int> stack(0); int temp; vector<int> visited(size); for(int i=0;i<size;i++){//入度为0的结点入栈 if(!events[i]->indegree){ stack.push_back(i); count++; visited[i]=1; } } while(!stack.empty()){//栈不为空 temp=stack.front(); stack.erase(stack.begin()); for(int i=0;i<size;i++){ if(!visited[i]&&vertexs[temp][i]<9999){//将所有入度为temp的结点 入度-1 if(!(--events[i]->indegree)){//如果入度为0则加入队列 visited[i]=1; stack.push_back(i); count++; for(int j=0;j<size;j++){//找出这个入度为0的结点中 前继结点到这个点的最大时间 if(vertexs[j][i]<9999 && visited[j] && events[j]->es + vertexs[j][i]> events[i]->es){ events[i]->es = events[j]->es + vertexs[j][i]; events[i]->keyEvent=j;//哪个结点到这个结点耗时最多 这个结点就是当前结点的关键路径 } } } } } } //如果count不等于events.size()说明存在环 if(count==size){ int max{0}; for(int i=0;i<size;i++){ if(events[i]->es>max){ max=events[i]->es; } } cout << max <<endl; return true; }else{ cout << "Impossible"<<endl; return false; } } }; int main(){ int n,m; cin >> n >> m; matricGraphic MG; MG.build(n, m); if(m>=n-1){ //如果是DAG有向无环图 MG.toplogicalSort(); }else{ cout << "Impossible"<<endl; } return 0; }
以上是关于数据结构 08-图8 How Long Does It Take (25 分)的主要内容,如果未能解决你的问题,请参考以下文章
08-图8 How Long Does It Take (25 分)
08-图8 How Long Does It Take (25分)