任何疑问、意见、建议请留言公众号:一航代码
题目描述:
读入任务调度序列,输出n个任务适合的一种调度方式。
输入格式:
输入包含多组测试数据。每组第一行输入一个整数n(n<100000),表示有n个任务。接下来n行,每行第一个表示前序任务,括号中的任务为若干个后序任务,表示只有在前序任务完成的情况下,后序任务才能开始。若后序为NULL则表示无后继任务。
输出格式:
输出调度方式,输出如果有多种适合的调度方式,请输出字典序最小的一种。
输入样例:
4
Task0(Task1,Task2)
Task1(Task3)
Task2(NULL)
Task3(NULL)
5
Task4(Task1,Task2)
Task2(Task3)
Task3(NULL)
Task1(Task0)
Task0(NULL)
4
Task3(Task2)
Task0(Task3,Task2)
Task1(Task2)
Task2(NULL)
5
Task1(Task2)
Task0(Task3,Task2)
Task2(Task4)
Task4(NULL)
Task3(NULL)
输出样例:
Task0 Task1 Task2 Task3
Task4 Task1 Task0 Task2 Task3
Task0 Task1 Task3 Task2
Task0 Task1 Task2 Task3 Task4
解决方法:
(1)代码实现:
#include <algorithm>
#include <iostream>
#include <math.h>
#include <queue>
#include <string>
#include <vector>
using namespace std;
//一航代码:拓扑排序+大顶堆解决2012中科大任务调度问题
int main()
{
int n;
while (cin >> n) {
getchar();
vector<int> indegree(n, 0);
vector<vector<int>> adjacent(n, vector<int>());
vector<int> v;
vector<int> res;
for (int i = 0; i < n; i++) {
adjacent.push_back(v);
}
for (int k = 0; k < n; k++) {
string s;
getline(cin, s);
int first = 0;
bool flag = true;//flag为true时,处理第一个任务。
for (int i = 0; i < (int)s.size(); i++) {
if (isdigit(s[i]) && flag) {
first = s[i] - '0';
flag = false;
} else if (isdigit(s[i]) && !flag) {
indegree[s[i] - '0']++;
adjacent[first].push_back(s[i] - '0');
}
}
}
priority_queue<int, vector<int>, greater<int>> myqueue;
for (int i = 0; i < n; i++) {
if (indegree[i] == 0) {
myqueue.push(i);
}
}
while (!myqueue.empty()) {
int cur = myqueue.top();
myqueue.pop();
res.push_back(cur);
for (int i = 0; i < (int)adjacent[cur].size(); i++) {
indegree[adjacent[cur][i]]--;
if (indegree[adjacent[cur][i]] == 0) {
myqueue.push(adjacent[cur][i]);
}
}
}
if ((int)res.size() == n) {
for (int i = 0; i < n - 1; i++) {
printf("Task%d ", res[i]);
}
printf("Task%d\n", res[n - 1]);
} else {
printf("error\n");
}
}
system("pause");
return 0;
}
/*
4
Task3(Task2)
Task0(Task3,Task2)
Task1(Task2)
Task2(NULL)
res:0 1 3 2
5
Task1(Task2)
Task0(Task3,Task2)
Task2(Task4)
Task4(NULL)
Task3(NULL)
res:0 1 2 3 4
*/