hdu5195 二分+线段树+拓扑序
这题说的给了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 二分+线段树+拓扑序的更多相关文章
- HDU4614 Vases and Flowers 二分+线段树
分析:感觉一看就是二分+线段树,没啥好想的,唯一注意,当开始摆花时,注意和最多能放的比大小 #include<iostream> #include<cmath> #includ ...
- Tsinsen A1505. 树(张闻涛) 倍增LCA,可持久化线段树,DFS序
题目:http://www.tsinsen.com/A1505 A1505. 树(张闻涛) 时间限制:1.0s 内存限制:512.0MB 总提交次数:196 AC次数:65 平均分: ...
- BZOJ_3252_攻略_线段树+dfs序
BZOJ_3252_攻略_线段树+dfs序 Description 题目简述:树版[k取方格数] 众所周知,桂木桂马是攻略之神,开启攻略之神模式后,他可以同时攻略k部游戏.今天他得到了一款新游戏< ...
- 【XSY2534】【BZOJ4817】树点涂色 LCT 倍增 线段树 dfs序
题目大意 Bob有一棵\(n\)个点的有根树,其中\(1\)号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同.定义一条路径的权值是:这条路径上的点(包括起点和终点)共有多少种不同的颜 ...
- J - Joseph and Tests Gym - 102020J (二分+线段树)
题目链接:https://cn.vjudge.net/contest/283920#problem/J 题目大意:首先给你n个门的高度,然后q次询问,每一次询问包括两种操作,第一种操作是将当前的门的高 ...
- Educational Codeforces Round 61 D 二分 + 线段树
https://codeforces.com/contest/1132/problem/D 二分 + 线段树(弃用结构体型线段树) 题意 有n台电脑,只有一个充电器,每台电脑一开始有a[i]电量,每秒 ...
- 【BZOJ-3110】K大数查询 整体二分 + 线段树
3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 6265 Solved: 2060[Submit][Sta ...
- hdu6070 Dirt Ratio 二分+线段树
/** 题目:hdu6070 Dirt Ratio 链接:http://acm.hdu.edu.cn/showproblem.php?pid=6070 题意:给定n个数,求1.0*x/y最小是多少.x ...
- 【bzoj4817】树点涂色 LCT+线段树+dfs序
Description Bob有一棵n个点的有根树,其中1号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同.定义一条路 径的权值是:这条路径上的点(包括起点和终点)共有多少种不同的颜色. ...
随机推荐
- stdarg.h头文件源代码分析
谈到C语言中可变参数函数的实现(参见C语言中可变参数函数实现原理),有一个头文件不得不谈,那就是stdarg.h 本文从minix源码中的stdarg.h头文件入手进行分析: #ifndef _STD ...
- DXP 内电层分割
多层电路板中间层设置与内电层如何分割 多层电路板与一般的电路板不同之处在于,多层电路板除了顶层和底层之外,还有若干中间层,这些中间层可以是信号层(mid layer),也可以是内部电源/接地层(int ...
- 让HTML标签、DIV、SPAN拥有focus事件和blur事件,聚焦和失焦
DIV和其他普通标签是不具有onfocus和onblur事件的.INPUT和A标签为什么拥有?而DIV和SPAN等普通标签却没有?有时候我们习惯性用键盘的TAB来移动光标,仔细看你会发现,光标只在IN ...
- python计算均值方差
用Python求均值与方差,可以自己写,也可以借助于numpy,不过到底哪个快一点呢? 我做了个实验,首先生成9百万个样本: nlist=range(0,9000000) nlist=[float(i ...
- [转][darkbaby]任天堂传——失落的泰坦王朝(下)
即使是日本业界人士也对1999年发生的“口袋妖怪所有权风波”知之甚少,实际上这个事件的结局足以改变游戏产业未来数十年的势力图,山内溥凭借着个人的睿智让任天堂再次渡过了命运的暗礁,而另一颗曾经炙手可热的 ...
- wpgcms---banner图怎么调用
使用wpgcms调用banner图,首先新建应用为 自定义应用,然后添加对应的字段信息,例如: 具体调用方式: <ul> {% set bannerlist = wpg.appdata.g ...
- Java String, StringBuffer和StringBuilder实例
1- 分层继承2- 可变和不可变的概念3- String3.1- 字符串是一个非常特殊的类3.2- String 字面值 vs. String对象3.3- String的方法3.3.1- length ...
- anaconda资源链接
清华源: https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/ anaconda所有版本大全: http://www.bubuko.com/in ...
- compile time - run-time
php.net Class member variables are called "properties". You may also see them referred to ...
- ArcCatalog连接ArcSDE连接报:unable to create new database connection file,permission is denied
参考博文:链接 ArcCatalog连接ArcSDE连接报:unable to create new database connection file,permission is denied 最近经 ...