问题 A: 任务调度
时间限制: 1 Sec 内存限制: 32 MB
提交: 40 解决: 27
题目描述
读入任务调度序列,输出n个任务适合的一种调度方式。
输入
输入包含多组测试数据。
每组第一行输入一个整数n(n<100000),表示有n个任务。
接下来n行,每行第一个表示前序任务,括号中的任务为若干个后序任务,表示只有在前序任务完成的情况下,后序任务才能开始。若后序为NULL则表示无后继任务。
输出
输出调度方式,输出如果有多种适合的调度方式,请输出字典序最小的一种。
样例输入
4
Task0(Task1,Task2)
Task1(Task3)
Task2(NULL)
Task3(NULL)
样例输出
Task0 Task1 Task2 Task3
经验总结
本题的注意点题目已经给的很清晰了,关键是要理清思路,善于使用STL,往往能事半功倍。
正确代码
#include <cstdio>
#include <iostream>
#include <unordered_map>
#include <queue>
#include <string>
using namespace std;
struct Task
{
string name;
int level;
friend bool operator <(const Task &t1,const Task &t2)
{
if(t1.level!=t2.level)
return t1.level>t2.level;
else
return t1.name>t2.name;
}
};
void dispose(string str,priority_queue<Task> &task,unordered_map<string,int> &list)
{
string first;
int pos;
int firstlevel;
pos=str.find('(');
first=str.substr(0,pos);
str.erase(0,pos+1);
if(list.count(first)==0)
{
Task newtask;
newtask.name=first;
newtask.level=0;
task.push(newtask);
firstlevel=list[first]=0;
}
else
{
firstlevel=list[first];
}
while(str.empty()==false)
{
string last;
pos=str.find(',');
if(pos==string::npos)
{
pos=str.find(')');
last=str.substr(0,pos);
str.clear();
}
else
{
last=str.substr(0,pos);
str.erase(0,pos+1);
}
if(last!="NULL")
{
Task newtask;
newtask.name=last;
newtask.level=firstlevel+1;
list[last]=newtask.level;
task.push(newtask);
}
}
}
int main()
{
int n;
while(~scanf("%d",&n))
{
priority_queue<Task> task;
unordered_map<string,int> list;
string temp;
for(int i=0;i<n;i++)
{
cin>>temp;
dispose(temp,task,list);
}
while(task.empty()==false)
{
cout<<task.top().name;
task.pop();
if(!task.empty())
{
cout<<" ";
}
}
list.clear();
}
return 0;
}