题意:排序输出:在先满足定约束条件下(如 3必需在1前面,7必需在4前面),在满足:1尽量前,其次考虑2,依次.....(即有次约束). 开始的时候,只用拓扑,然后每次在都可以选的时候,优先考虑小的,其实没什么简单,如 图(3-->1,2)这样输出是2.3.1,正确应该是 3 1 2,因为 1要尽量前(都满足第一约束). 参考他人思路结合自己理解:因为这样的弊端就是没有考虑这种情况:图中:若我的"子孙"中,有的比你次优先,虽然现在我们都可以输出,但是要考虑我的子代,若我的子代有次…
pid=4857">hdu4857 逃生 题目是求拓扑排序,但不是依照字典序最小输出,而是要使较小的数排在最前面. 一開始的错误思路:给每一个点确定一个优先级(该点所能到达的最小的点).然后用拓扑排序+优先对列正向处理,正向输出.这是错误的.例如以下例子: 1 5 4 5 2 4 3 2 1 3 1 正确的解法:是反向建边.点大的优先级高,用拓扑排序+优先队列,逆向输出序列就可以. 依据每对限制,可确定拓扑序列,但此时的拓扑序列可能有多个(没有之间关系的点的顺序不定).本题要求较小的点排到…
尤其要注意拓扑的分层问题 不难理解 就是不怎么好想到 拓扑的思路这里就不累述了 #include <iostream> #include <cstdio> #include <cstring> #include <vector> #include <queue> #define maxn 30007 using namespace std; int T; int n,m; int in[maxn]; vector<int> edge[…
逃生 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Problem Description 糟糕的事情发生啦,现在大家都忙着逃命.但是逃命的通道很窄,大家只能排成一行. 现在有n个人,从1标号到n.同时有一些奇怪的约束条件,每个都形如:a必须在b之前.同时,社会是不平等的,这些人有的穷有的富.1号最富,2号第二富,以此类推.有钱人就贿赂负责人,所以他们有一些好处. 负责人现在…
/*一组测试实例 4 4 2 3 1 2 4 */ #include<stdio.h> #include<string.h> #include<queue> using namespace std; #define N 31000 struct node { int u,v,next; }bian[N*10]; int head[N],yong,indegree[N],n,f[N],len; void init() { memset(head,-1,sizeof(hea…
n个数,已经有大小关系,现给m个约束,规定a在b之前,剩下的数要尽可能往前移.输出序列 大小关系显然使用拓扑结构,关键在于n个数本身就有大小关系,那么考虑反向建图,优先选择值最大的入度为零的点,这样得到的序列就是从大到小的,最后倒序输出就行了. 写这题的时候头好痛阿肚子好痛阿,再也不想熬夜了,一点效率都没有. /** @Date : 2017-09-29 19:29:12 * @FileName: HDU 4857 拓扑排序 + 优先队列.cpp * @Platform: Windows * @…
#include<iostream> #include <queue> using namespace std; int main() { //对于基础类型 默认是大顶堆 priority_queue<int> a; //等同于 priority_queue<int, vector<int>, less<int> > a; // 这里一定要有空格,不然成了右移运算符↓ priority_queue<int, vector<…
两个题目的意思差不多 都是希望得出的拓扑序如果有多种 要求输出字典序小的情况 这里引用一个大佬的博客 关于为什么不能直接建图然后用小根堆解决这个问题(http://blog.csdn.net/rgnoH/article/details/75253355 : 出处) 再解答一个小问题: 主要是在和六号@Mogician_Evian 交流之后想到的:这道题可以用小根堆做吗? 看起来可以! 可能的操作是: 1.题目中说什么,就怎么连边,并记录入度. 2.执行Topsort标准操作,压入小根堆中. 此时…
题目描述 知名美食家小 A被邀请至ATM 大酒店,为其品评菜肴. ATM 酒店为小 A 准备了 N 道菜肴,酒店按照为菜肴预估的质量从高到低给予 1到N的顺序编号,预估质量最高的菜肴编号为1.由于菜肴之间口味搭配的问题, 某些菜肴必须在另一些菜肴之前制作,具体的,一共有 M 条形如“i 号菜肴‘必须’ 先于 j 号菜肴制作”的限制,我们将这样的限制简写为<i,j>.现在,酒店希望能求 出一个最优的菜肴的制作顺序,使得小 A能尽量先吃到质量高的菜肴:也就是说, (1)在满足所有限制的前提下,1…
题目描述 给你一张有向图,问:编号-位置序(即每个编号的位置对应的序列)最小(例如1优先出现在前面,1位置相同的2优先出现在前面,以此类推)的拓扑序是什么? 输入 第一行是一个正整数D,表示数据组数. 接下来是D组数据. 对于每组数据:  第一行两个用空格分开的正整数N和M,分别表示菜肴数目和制作顺序限制的条目数.  接下来M行,每行两个正整数x,y,表示“x号菜肴必须先于y号菜肴制作”的限制.(注意:M条限制中可能存在完全相同的限制)  输出 输出文件仅包含 D 行,每行 N 个整数,表示最优…
HDU 4857 (反向拓扑排序 + 优先队列) 糟糕的事情发生啦,现在大家都忙着逃命.但是逃命的通道很窄,大家只能排成一行. 现在有n个人,从1标号到n.同时有一些奇怪的约束条件,每个都形如:a必须在b之前. 同时,社会是不平等的,这些人有的穷有的富.1号最富,2号第二富,以此类推.有钱人就贿赂负责人,所以他们有一些好处. 负责人现在可以安排大家排队的顺序,由于收了好处,所以他要让1号尽量靠前,如果此时还有多种情况,就再让2号尽量靠前,如果还有多种情况,就让3号尽量靠前,以此类推. 那么你就要…
CJOJ 2482 [POI2000]促销活动(STL优先队列,大根堆,小根堆) Description 促销活动遵守以下规则: 一个消费者 -- 想参加促销活动的消费者,在账单下记下他自己所付的费用,他个人的详细情况,然后将账单放入一个特殊的投票箱. 当每天促销活动结束时,从投票箱中抽出两张账单: 第一张被抽出的账单是金额最大的账单 然后被抽出的是金额最小的账单,对于付了金额最大账单的这位消费者,将得到一定数目的奖金,其奖金数等于他账单上的金额与选出的最小金额的差. 为了避免一个消费者多次获奖…
Description 公交车一共经过N(1<=N<=20000)个站点,从站点1一直驶到站点N.K(1<=K<=50000)群奶牛希望搭乘这辆公交车.第i群牛一共有Mi(1<=Mi<=N)只. 他们希望从Si到Ei去.公交车只能座C(1<=C<=100)只奶牛.而且不走重复路线,请计算这辆车最多能满足多少奶牛听要求.注意:对于每一群奶牛,可以部分满足,也可以全部满足,也可以全部不满足. Input 第1行: 三个整数: K,N,C. 由空格隔开. 第2..…
题目传送门 用优先队列瞎搞... 想着在每个地方 先算上一个点到这一个点要花费多少钱 这个用小根堆算就好 然后在这个地方加油 把油钱比自己多的替代掉 这个用大根堆维护一下 然后两个堆之间信息要保持互通 这个有点麻烦 我用的f数组维护 这样就好了 中间懒得改全部开了long long 不要介意 #include<cstdio> #include<cstring> #include<algorithm> #include<queue> #include<i…
逃生 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 877 Accepted Submission(s): 236 Problem Description 糟糕的事情发生啦,如今大家都忙着逃命.可是逃命的通道非常窄,大家仅仅能排成一行. 如今有n个人,从1标号到n.同一时候有一些奇怪的约束条件,每一个都形如:a必须在b之前. 同一时候,社会…
和bzoj4504差不多,就是换了个数据结构 像超级钢琴一样把五元组放进大根堆,每次取一个出来拆开,(d,l,r,p,v)表示右端点为d,左端点区间为(l,r),最大区间和值为v左端点在p上 关于怎么快速求区间和,用一个可持久trie上维护最大xor值和对应的点即可 #include<iostream> #include<cstdio> #include<queue> //#include<ctime> using namespace std; const…
像超级钢琴一样把五元组放进大根堆,每次取一个出来拆开,(d,l,r,p,v)表示右端点为d,左端点区间为(l,r),最大区间和值为v左端点在p上 关于怎么快速求区间和,用可持久化线段树维护(主席树?)每个点到他root的区间和,这样每次右端点右移就是上一个的线段树在(la[a[i]]+1,i)加上a[i],la是这个值a[i]上一次出现的位置 然后就可以在线处理询问了 有一点因为这个线段树建的是1~n,所以右端点不是n的时候取max会取到右端点向右还是初始值0的位置(有可能前面是负数),这样的解…
题意:每一个人的基础工资是888. 因为一部分人要显示自己水平比較高,要求发的工资要比其它人中的一个人多.问你能不能满足他们的要求,假设能的话终于一共要发多少钱,假设不能就输出-1. 策略:拓扑排序. 这道题有些难点:一:数据大,建二维数组肯定不行,要换其它的数据结构(vector, 或者是链式前向星(本题代码用的是链式前向星)): 二:要逆拓扑排序(就是将++in[b]换成++in[a]). 三要分层次(依据上一个的钱数+1就可以). 不懂什么是链式前向星 移步:http://blog.csd…
奖学金 题目描述 小张学院有 \(c\) 名学生,第 \(i\) 名学生的成绩为 \(ai\) ​,要获得的奖学金金额为 \(bi\) . 要从这 \(c\) 名学生中挑出 \(n\) 名学生发奖学金.这个神秘人物爱好奇特,他希望得到奖学金的同学的成绩的中位数尽可能大,但同时,他们的奖学金总额不能超过 \(f\) . 输入格式 第一行有三个整数,分别表示要挑出的学生人数 \(n\) ,学生总人数 \(c\) 和奖学金总额的最大值 \(f\) . 第 \(2\) 到第 \((c+1)\) 行,每行…
传送门:F - Keep Connect (atcoder.jp) 题意: 给定长度为N的操作(ti,yi). 给定初值为0的x,对其进行操作:当t为1时,将x替换为y:当t为2时,将x加上y. 最多可以跳过k步,求最终x的最大值. 思路: 注意到,当t为1时,进行替换操作,那么该位置前面的操作是不会对后面产生任何影响的,也就不会消耗k. 那么我们可以枚举最后一次不跳过的1操作,对于该位置的前面无需考虑,对于该位置的后面:所有的1操作都应跳过(记数量为cnt),且对于2操作选择数值前k - cn…
堆排序是一种树形选择排序方法,它的特点是:在排序的过程中,将array[0,...,n-1]看成是一颗完全二叉树的顺序存储结构,利用完全二叉树中双亲节点和孩子结点之间的内在关系,在当前无序区中选择关键字最大(最小)的元素. 1. 若array[0,...,n-1]表示一颗完全二叉树的顺序存储模式,则双亲节点指针和孩子结点指针之间的内在关系如下: 任意一节点指针 i:父节点:i==0 ? null : (i-1)/2  左孩子:2*i + 1  右孩子:2*i + 2 2. 堆的定义:n个关键字序…
pid=2647">原文地址 题目分析 题意 老板发工资,可是要保证发的工资数满足每一个人的期望,比方A期望工资大于B,仅仅需比B多1元钱就可以.老板发的最低工资为888元.输出老板最少发的工资总数.若是无法满足大家的期望,则输出-1. 分析 非常明显这是一个拓扑问题.若存在环则无法满足大家的期望.若按常理,A>B,则可能会建立A指向B的有向边.此题不然,由于我们仅仅知道最少的钱数是888,所以从小到大进行拓扑排序更为恰当.所以是建立B指向A的有向边. 此之为逆拓扑排序.由于这样处理…
Description 给定一棵n个节点的有根树,编号依次为1到n,其中1号点为根节点.每个点有一个权值v_i. 你需要将这棵树转化成一个大根堆.确切地说,你需要选择尽可能多的节点,满足大根堆的性质:对于任意两个点i,j,如果i在树上是j的祖先,那么v_i>v_j. 请计算可选的最多的点数,注意这些点不必形成这棵树的一个连通子树. Input 第一行包含一个正整数n(1<=n<=200000),表示节点的个数. 接下来n行,每行两个整数v_i,p_i(0<=v_i<=10^9…
Description 给定一棵n个节点的有根树,编号依次为1到n,其中1号点为根节点.每个点有一个权值v_i. 你需要将这棵树转化成一个大根堆.确切地说,你需要选择尽可能多的节点,满足大根堆的性质:对于任意两个点i,j,如果i在树上是j的祖先,那么v_i>v_j. 请计算可选的最多的点数,注意这些点不必形成这棵树的一个连通子树. Solution 思路比较直接 设 \(f[i][j]\) 表示\(i\)为子树的节点中,堆中最大值小于\(j\)的情况下能选的最多点数 转移时就是用一个前缀最大值更…
Description 给定一棵n个节点的有根树,编号依次为1到n,其中1号点为根节点.每个点有一个权值v_i. 你需要将这棵树转化成一个大根堆.确切地说,你需要选择尽可能多的节点,满足大根堆的性质:对于任意两个点i,j,如果i在树上是j的祖先,那么v_i>v_j. 请计算可选的最多的点数,注意这些点不必形成这棵树的一个连通子树. Input 第一行包含一个正整数n(1<=n<=200000),表示节点的个数. 接下来n行,每行两个整数v_i,p_i(0<=v_i<=10^9…
[BZOJ4919][Lydsy六月月赛]大根堆 Description 给定一棵n个节点的有根树,编号依次为1到n,其中1号点为根节点.每个点有一个权值v_i. 你需要将这棵树转化成一个大根堆.确切地说,你需要选择尽可能多的节点,满足大根堆的性质:对于任意两个点i,j,如果i在树上是j的祖先,那么v_i>v_j. 请计算可选的最多的点数,注意这些点不必形成这棵树的一个连通子树. Input 第一行包含一个正整数n(1<=n<=200000),表示节点的个数. 接下来n行,每行两个整数v…
4919: [Lydsy1706月赛]大根堆 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 599  Solved: 260[Submit][Status][Discuss] Description 给定一棵n个节点的有根树,编号依次为1到n,其中1号点为根节点.每个点有一个权值v_i. 你需要将这棵树转化成一个大根堆.确切地说,你需要选择尽可能多的节点,满足大根堆的性质:对于任意两个点i,j,如果i在树上是j的祖先,那么v_i>v_j. 请计算…
大根堆的定义:1 大根堆是一个大根树 2 大根堆是一个完全二叉树 所以大根堆用数组表示是连续的,不会出现空白字段. 对于大根堆的插入 对于大根堆的插入,可以在排序前确定大根堆的形状,可以确定元素5从位置6插入,那么比较元素5和位置3的元素2, 元素5比元素2大,将2下移.接着比较元素5和元素20,一次类推,直到找到元素5的合理位置. 接着看一下如果插入的元素是21,怎么进行排序. 21比2大,所以将2下移,接着比较21和20,发现20比21小,20下移,最终21放到 根的位置.形成大根堆. 对于…
实现堆排序的算法思路是先创建堆,也就是从叶子节点起对每一层的孩子节点及其对应位置的父亲节点进行比较,较大的孩子节点替换较小的父亲节点,一级一级比较替换,就创建出了大根堆,小根堆反之.创建好大根堆以后,我们,将整棵树的根节点与最后最后一个节点替换位置,然后去除最后一个节点,在创建一个新的大根堆,以此类推,完成排序.代码如下: /** * <p>堆排序 * @param int[] arr * @return int[] * */ public int[] heapSort(int[] arr){…
HDU.2647 Reward(拓扑排序 TopSort) 题意分析 裸的拓扑排序 详解请移步 算法学习 拓扑排序(TopSort) 这道题有一点变化是要求计算最后的金钱数.最少金钱值是888,最少的差额是1,如1号的人比2号钱要多,2号至少是1号人的钱数+1.根据拓扑排序的思想,我们只需要类比二叉树的层序遍历,每次取出入度为0的节点做处理,累加金钱数量,然后再取出入度为0的节点处理.直到取出所有的点或者判断成环即可. 代码总览 #include <iostream> #include <…