目录
问题 A: 任务调度
题目描述
读入任务调度序列,输出n个任务适合的一种调度方式。
输入
输入包含多组测试数据。
每组第一行输入一个整数n(n<100000),表示有n个任务。
接下来n行,每行第一个表示前序任务,括号中的任务为若干个后序任务,表示只有在前序任务完成的情况下,后序任务才能开始。若后序为NULL则表示无后继任务。
输出
输出调度方式,输出如果有多种适合的调度方式,请输出字典序最小的一种。
样例输入
4
Task0(Task1,Task2)
Task1(Task3)
Task2(NULL)
Task3(NULL)
样例输出
Task0 Task1 Task2 Task3
题解
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <set>
#include <string>
#include <map>
#include <queue>
#include <algorithm>
using namespace std;
struct task{
string name;//任务名字
int priority;//任务优先数
friend bool operator < (task a, task b){//比较符号小于的重载
if(a.priority != b.priority){
return a.priority > b.priority;
}
else{
return a.name > b.name;
}
}
};
void load(string s, priority_queue<task> &pq, map<string, int> &have){
string word = "";
task t;
int i;
for(i = 0; s[i] != '('; i++){
word = word + s[i];
}
if(have[word] == 0){//第一次出现则记录该任务,并初始化其优先数为最低,即优先级最大
t.name = word;
t.priority = 1;
have[word] = t.priority;//在map序列中做记录
pq.push(t);//加入优先队列
}
s.erase(s.begin(), s.begin() + s.find("(") + 1);//删除左括号及以前的字符串
int temp = have[word] + 1;
word = "";
for(i = 0; i < s.size(); i++){
if((s[i] == ',' || s[i] == ')') && (word != "NULL" && have[word] == 0)){//这个任务不是NULL并且是第一次出现就进行处理
t.name = word;
t.priority = temp;
have[word] = t.priority;
pq.push(t);
word = "";
}
else{
word = word + s[i];
}
}
}
int main(){
int n;
while(scanf("%d", &n) != EOF){
priority_queue<task> pq;
map<string, int> have;
string s;
int i;
for(i = 0; i < n; i++){
cin >> s;
load(s, pq, have);
}
while(!pq.empty()){
cout << pq.top().name;
if(pq.size() > 1){
cout << " ";
}
else{
cout << endl;
}
pq.pop();
}
}
return 0;
}