zoukankan      html  css  js  c++  java
  • 【拓扑习题】课程安排问题

    时间限制:1 s  内存限制:128 MB
    【问题描述】

    一个软件专业的学生必须学习一 系列基本课程,其中有些课程是基础课,它独立于其它课程,如《高等数学》、《计算引论》;而另一些课程必须在学完作为它的基础的先修课程才能开始。如,在 《程序设计基础》和《离散数学》学完之前就不能开始学习《数据结构》。这些先决条件定义了课程之间的领先(优先)关系。请你在符合上述领先(优先)条件的 前提下,给出所有课程的一个有序序列,以方便学校排课。
    【输入格式】
    输入文件有若干行
    第一行,一个整数n,表示共有n(0<n<=100)门课程
    第2--n+1行分别表示第1--n门课程的先修课程信息,每行有若干个整数m,s1,s2,...,sm
    m表示该门课程有m门先修课程,s1,s2,...,sm分别表示m门先修课的编号,如果该门课没有先修课程,则m为0。
    【输出格式】
    一行,n个整数,表示n门课程编号的有序序列(如果这样的序列不存在,则输出no;如果有多个这样的序列,输出字典序最小的)
    【输入输出样例】
    输入文件名: curriculum.in
    4
    0
    1 1
    1 1
    2 2 3
    输出文件名:curriculum.out
    1 2 3 4

    【分析】
     这应该也算是经典习题了吧。。这里就当是恢复状态→_→
    首先这是个很明显的topo sort,但由于题目丧心病狂地要求最小字典序,这里不得不把算导上介绍的DFS换成基于最小堆的层次遍历算法……OMG,堆的代码之前已经练过了,那么这里就用STL水过去吧。
     1 #include <cstdio>
     2 #include <fstream>
     3 #include <queue> //priority_heap
     4 #include <vector> 
     5 #include <functional> //use of FUNCTOR "greater<int>"
     6 using namespace std;
     7 ifstream in("curriculum.in");
     8 ofstream out("curriculum.out");
     9 bool settled[102]={0};
    10 int M[102]={0};
    11 int N;
    12 int ans[102], last = 0;
    13 vector <int> Next[102];
    14 priority_queue <int, vector<int>, greater<int> >Q;
    15 void init()
    16 {
    17     int i, j, k;
    18     for(i = 1;i <=N; ++i)
    19     {
    20         in >> M[i];
    21         if(!M[i]) //Roots
    22             Q.push(i);
    23         else for(j = 0;j < M[i];++j)
    24         {
    25             in >> k;
    26             Next[k].push_back(i);
    27         }
    28     }
    29 }
    30 void Topo()
    31 {
    32     int k;
    33     vector <int>::iterator it;
    34     while(!Q.empty())
    35     {
    36         k = Q.top();Q.pop();
    37         ans[last++] = k;
    38         settled[k] = 1;
    39         for(it = Next[k].begin();it!=Next[k].end();++it)
    40         {
    41             if(!settled[*it])
    42             {
    43                 M[*it]--;
    44                 if(!M[*it])Q.push(*it);
    45             }
    46             else return;//ring
    47         }
    48     }
    49 }
    50 int main()
    51 {
    52     int i;
    53     ios::sync_with_stdio(0);
    54     in >> N;
    55     init();
    56     Topo();
    57     if(last != N)
    58         out << "no";
    59     else for(i = 0;i < N; ++i)
    60         out << ans[i] << ' ';
    61     return 0;
    62 }

  • 相关阅读:
    刷题-力扣-541. 反转字符串 II
    刷题-力扣-515. 在每个树行中找最大值
    刷题-力扣-513. 找树左下角的值
    刷题-力扣-404. 左叶子之和
    刷题-力扣-257. 二叉树的所有路径
    刷题-力扣-226. 翻转二叉树
    刷题-力扣-236. 二叉树的最近公共祖先
    刷题-力扣-235. 二叉搜索树的最近公共祖先
    刷题-力扣-145. 二叉树的后序遍历
    扛把子组2018092609-2 选题 Scrum立会报告+燃尽图 06
  • 原文地址:https://www.cnblogs.com/Asm-Definer/p/3805092.html
Copyright © 2011-2022 走看看