【算法笔记第6.6节 priority_queue 】问题 A: 任务调度(有点难)

问题 A: 任务调度

时间限制: 1 Sec  内存限制: 32 MB
提交: 102  解决: 72
[提交][状态][讨论版][命题人:外部导入]

题目描述

读入任务调度序列,输出n个任务适合的一种调度方式。

输入

输入包含多组测试数据。

每组第一行输入一个整数n(n<100000),表示有n个任务。

接下来n行,每行第一个表示前序任务,括号中的任务为若干个后序任务,表示只有在前序任务完成的情况下,后序任务才能开始。若后序为NULL则表示无后继任务。

输出

输出调度方式,输出如果有多种适合的调度方式,请输出字典序最小的一种。

样例输入

4
Task0(Task1,Task2)
Task1(Task3)
Task2(NULL)
Task3(NULL)

样例输出

Task0 Task1 Task2 Task3

设置优先级,第一行输出的第一个把优先级设置为0,之后的优先级数值一次是前1个优先级数值加1.优先级依次降低。

按照优先级高的排序依次输出。

#include<stdio.h>
#include<algorithm>
#include<iostream>
#include<queue>
#include<map>
using namespace std;
int n;
struct task
{
    string name;
    int priority;
    friend bool operator<(const task &t1, const task &t2)
    {
        if(t1.priority!=t2.priority)
            return t1.priority > t2.priority;//输出优先级大的
        else
            return t1.name > t2.name;//输出字典序小的
    }
};
void deal(string s, priority_queue<task> &p, map<string, int> &list)
{
    string now = "";
    task t;
    int i=0;
    //处理第一个
    while(s[i]!='(')
    {
        now+=s[i];
        i++;
    }
    if(list[now]==0)//第一个
    {
        t.name = now;
        t.priority = 0;
        list[now] = 0;
        p.push(t);
    }
    s.erase(s.begin(), s.begin()+i);//删除Task0
    s.erase(s.begin());//删除(
    int temp = list[now]+1;
    i=0;
    now = "";


    //处理括号里面的
    while(i<s.size())
    {
        if((s[i]==','||s[i]==')')&&list[now]==0&&now!="NULL")
        {
            t.name = now;
            t.priority = temp;
            list[now] = temp;
            p.push(t);
            //cout<<now<<" "<<temp <<endl;
            now = "";
        }
        else
            now+=s[i];
        i++;
    }
}
int main()
{

    while(scanf("%d",&n)!=EOF)
    {
        priority_queue<task> p;
        map<string, int> list;//名字---优先级
        for(int i=0; i<n; i++)
        {
            string s;
            cin>>s;
            deal(s, p, list);
        }
        while(p.empty()!=1)
        {
            cout<<p.top().name;
            if(p.size()>1)
                cout<<" ";
            else
                cout<<endl;
            p.pop();
        }
    }
    return 0;
}

 

 

同样的解法不同的写法

#include<stdio.h>
#include<string.h>
#include<queue>
#include<map>
#include<algorithm>
using namespace std;
struct node
{
    int no;//编号
    int prior;
};
struct cmp
{
    bool operator()(node a, node b)
    {
        if(a.prior!=b.prior) return a.prior > b.prior;//按照优先级
        else    return a.no > b.no;//按照名字
    }
};
char a[1000001];
int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        getchar();
        priority_queue<node, vector<node>, cmp> q;
        map<int,int> p;//存放优先级
        for(int i=0; i<n; i++)
        {
            scanf("%s",a);
            int i1=4, n1=0;
            while(a[i1]!='(')//第一个任务
                    n1=n1*10+a[i1++]-'0';
            node t;
            t.no = n1;
            if(i==0)//是否是所有任务中的第一个
            {
                t.prior = 0;
                q.push(t);
            }
            else
                t.prior = p[t.no];

            int i2= 6, n2=0;
            if(a[i2]=='N')
                continue;
            while(i2 < strlen(a))
            {
                if(a[i2]>='0'&&a[i2]<='9')  n2 = n2*10+a[i2]-'0';
                if(a[i2]==','||a[i2]==')')
                {
                    if(p[n2]==0)//队列中没有
                    {
                        node tt;
                        tt.no=n2;
                        tt.prior = t.prior+1;
                        q.push(tt);
                        n2 = 0;
                        p[n2]= tt.prior;
                    }
                }
                i2++;
            }
        }
        while(q.size()>=1)
        {
            node t = q.top();
            q.pop();
            printf("Task%d ", t.no);
        }
    }
}

 

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值