这题说的给了n个点m条边要求保证是一个有向无环图,可以删除至多k条边使得这个图的拓扑序的字典序最大,我们知道如果我们要排一个点的时候一定要考虑比他大的点是否可以、通过拆边马上拆出来,如果可以拆当然是拆,肯定保证字典序最大,如果不能拆,就不拆留着以后拆,当初这个比他大的点度数小于k的,最大是多少,这个方法我一直想不出,后来看了题解,二分加线段树,可以做到,线段树维护每个点的d[i],然后通过二分找出小于k的最大点是多少。

 #include <iostream>
#include <algorithm>
#include <string.h>
#include <vector>
#include <cstdio>
#include<queue>
using namespace std;
const int maxn =;
struct Edge{
int u,v;
Edge(int uu=, int vv=){
u= uu; v =vv;
}
};
vector<Edge> E;
vector<int> G[maxn],REG[maxn];
void add_edg(int u, int v){
E.push_back(Edge(u,v));
G[u].push_back(E.size()-);
REG[v].push_back(E.size()-);
}
int ind[maxn];
int cL, cR,cans;
struct Itree{
int id[maxn*];
void build(int O, int L, int R){
if(L==R){
id[O] = ind[L] ; return ;
}
int mid = ( L + R ) >> ;
build(O*,L,mid);
build(O*+,mid+,R);
id[O]=min(id[O*],id[O*+]);
}
void update(int o, int L, int R){
if( L == R ){
id[o] = cans; return ;
}
int mid=(L+R)>>;
if(cL<=mid){
update(o*,L,mid);
}else update(o*+,mid+,R);
id[o]=min(id[o*],id[o*+]);
}
void query(int o , int L, int R){
if(cL<=L && cR>=R){
cans =min(cans,id[o]);return ;
}
int mid = (L+R)>>;
if(cL <= mid) query(o*,L,mid);
if(cR>mid) query(o*+,mid+,R);
}
}T;
bool use[maxn];
void init(int n){
for(int i=; i<n; i++){
G[i].clear();
REG[i].clear();
}
E.clear();
memset(ind,,sizeof(ind));
memset(use,true,sizeof(use));
}
int jud(int k, int n){
int L=,R=n,ans=-;
while(L<=R){
int mid = (L+R)>>;
cans = k+;
cL=mid; cR=R;
T.query(,,n);
if(cans<=k){
ans=mid; L=mid+;
}
else R=mid-;
}
return ans;
}
priority_queue<int> Q;
void solve1(int nk,int k,int n){ for(int i=; i<REG[nk].size(); i++){
use[ REG[nk][i] ] = false;
}
cans = k+;
cL=cR=nk;
T.update(,,n);
}
void solve2(int nk,int k,int n){
for(int i=; i<G[nk].size(); i++){
int numedg = G[nk][i];
if(use[numedg]){
use[numedg]=false;
Edge q = E[numedg];
ind[q.v]--;
if(ind[q.v]==){
Q.push(q.v); ind[q.v]=k+;
}
cL = cR = q.v;
cans =ind[q.v];
T.update(,,n);
}
}
}
int ans[maxn];
int main()
{
int n,m,k; while(scanf("%d%d%d",&n,&m,&k)==){
init(n);
for(int i=; i<m; i++){
int u,v;
scanf("%d%d",&u,&v);
add_edg(u,v);
ind[v]++;
}
while(!Q.empty())Q.pop();
for(int i =; i<=n; i++){
if(ind[i]==){
Q.push(i);
ind[i]=k+;
}
}
T.build(,,n);
int st=;
while(!Q.empty()){
int top = Q.top();
int nk = jud(k,n);
if(nk>top){
k-=ind[nk];
solve1(nk,k,n);
Q.push(nk);
}else{
Q.pop();
ans[st++]=top;
solve2(top,k,n);
}
}
for(int i=; i<n-; i++) printf("%d ",ans[i]);
printf("%d\n",ans[n-]);
} return ;
}

hdu5195 二分+线段树+拓扑序的更多相关文章

  1. HDU4614 Vases and Flowers 二分+线段树

    分析:感觉一看就是二分+线段树,没啥好想的,唯一注意,当开始摆花时,注意和最多能放的比大小 #include<iostream> #include<cmath> #includ ...

  2. Tsinsen A1505. 树(张闻涛) 倍增LCA,可持久化线段树,DFS序

    题目:http://www.tsinsen.com/A1505 A1505. 树(张闻涛) 时间限制:1.0s   内存限制:512.0MB    总提交次数:196   AC次数:65   平均分: ...

  3. BZOJ_3252_攻略_线段树+dfs序

    BZOJ_3252_攻略_线段树+dfs序 Description 题目简述:树版[k取方格数] 众所周知,桂木桂马是攻略之神,开启攻略之神模式后,他可以同时攻略k部游戏.今天他得到了一款新游戏< ...

  4. 【XSY2534】【BZOJ4817】树点涂色 LCT 倍增 线段树 dfs序

    题目大意 ​ Bob有一棵\(n\)个点的有根树,其中\(1\)号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同.定义一条路径的权值是:这条路径上的点(包括起点和终点)共有多少种不同的颜 ...

  5. J - Joseph and Tests Gym - 102020J (二分+线段树)

    题目链接:https://cn.vjudge.net/contest/283920#problem/J 题目大意:首先给你n个门的高度,然后q次询问,每一次询问包括两种操作,第一种操作是将当前的门的高 ...

  6. Educational Codeforces Round 61 D 二分 + 线段树

    https://codeforces.com/contest/1132/problem/D 二分 + 线段树(弃用结构体型线段树) 题意 有n台电脑,只有一个充电器,每台电脑一开始有a[i]电量,每秒 ...

  7. 【BZOJ-3110】K大数查询 整体二分 + 线段树

    3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 6265  Solved: 2060[Submit][Sta ...

  8. hdu6070 Dirt Ratio 二分+线段树

    /** 题目:hdu6070 Dirt Ratio 链接:http://acm.hdu.edu.cn/showproblem.php?pid=6070 题意:给定n个数,求1.0*x/y最小是多少.x ...

  9. 【bzoj4817】树点涂色 LCT+线段树+dfs序

    Description Bob有一棵n个点的有根树,其中1号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同.定义一条路 径的权值是:这条路径上的点(包括起点和终点)共有多少种不同的颜色. ...

随机推荐

  1. H3C系列之三层交换机dhcp功能的开启

    环境介绍>>>>>>>>>>>>>>>>>>>>交换机名牌:H3C交换机类型:三 ...

  2. python unittest框架中addCleanup函数详解

    接上一篇doCleanups说明,这次介绍下另一个很好用的函数:addCleanup 还是老规矩,看官方文档说明: addCleanup(function, *args, **kwargs)¶ Add ...

  3. selenium中javascript调试

    之前写了使用js输入长文件的文章,有同事在使用时,发现竟然无法输入,也不知道是什么原因,且用的还是id方式. 在参考网文后,才发现是js写的有问题,现总结一下 javascript调试,在firefo ...

  4. 解决远程登陆Linux误按ctrl+s锁屏

      很多刚从windows转移到linux上来工作的朋友,在用vi/vim编辑文件时,常常会习惯性的按下Ctrl+s来保存文件内容.殊不知这样按下去后面会造成整个终端不响应了,ssh连接还好说,直接关 ...

  5. iOS - 开源框架、项目和学习资料汇总(网络篇)

    网络连接 1. AFNetworking – ASI不升级以后,最多人用的网络连接开源库,[推荐]iOS网络编程之AFNetworking使用,iOS开发下载文件速度计算.2. Alamofire – ...

  6. MPU6050滤波、姿态融合(一阶互补、卡尔曼)

    前几天做了6050原始数据的串口输出和上位机波形的查看.这篇博客我们来看一下对原始数据的处理. 任务:利用STC89C52RC对MPU6050原始数据进行滤波与姿态融合. 首先我摘抄了一段别人在昨晚这 ...

  7. PyCharm+Eclipse共用Anaconda的数据科学环境

    1.安装anaconda2 安装好之后,本地python环境就采用anaconda自带的python2.7的环境. 2.安装py4j 在本地ctrl+r打开控制台后,直接使用pip安装py4j,因为a ...

  8. SHU 413 - 添加好友

    题目链接:http://acmoj.shu.edu.cn/problem/413/ 不难发现,这题是求C(n,1)+C(n,2)+C(n,3)+……+C(n,n-1)+C(n,n) 根据二项展开式有( ...

  9. 【作业】 iterator,set_union 一些奇怪的语法

    关于set_union系列函数(需要有序)的第五个参数,output iterator. 网上都是用inserter(c,c.begin()) 但vs会编译报错 所以改成了back_inserter, ...

  10. CodeForces - 586C Gennady the Dentist 模拟(数学建模的感觉)

    http://codeforces.com/problemset/problem/586/C 题意:1~n个孩子排成一排看病.有这么一个模型:孩子听到前面的哭声自信心就会减弱:第i个孩子看病时会发出v ...