DZY Loves Topological Sorting

Problem Description
A topological sort or topological ordering of a directed graph is a linear ordering of its vertices such that for every directed edge (u→v) from vertex u to vertex v , u comes before v in the ordering.
Now, DZY has a directed acyclic graph(DAG). You should find the lexicographically largest topological ordering after erasing at most k

edges from the graph.

 
Input
The input consists several test cases. (TestCase≤5

)
The first line, three integers n,m,k(1≤n,m≤105,0≤k≤m)

.
Each of the next m

lines has two integers: u,v(u≠v,1≤u,v≤n)

, representing a direct edge(u→v)

.

 
Output
For each test case, output the lexicographically largest topological ordering.
 
Sample Input
5 5 2
1 2
4 5
2 4
3 4
2 3
3 2 0
1 2
1 3
 
Sample Output
5 3 1 2 4
1 3 2

Hint

Case 1.
Erase the edge (2->3),(4->5).
And the lexicographically largest topological ordering is (5,3,1,2,4).

 
题解:因为我们要求最后的拓扑序列字典序最大,所以一定要贪心地将标号越大的点越早入队。我们定义点ii的入度为d_id​i​​。假设当前还能删去kk条边,那么我们一定会把当前还没入队的d_i\leq kd​i​​≤k的最大的ii找出来,把它的d_id​i​​条入边都删掉,然后加入拓扑序列。可以证明,这一定是最优的。

具体实现可以用线段树维护每个位置的d_id​i​​,在线段树上二分可以找到当前还没入队的d_i\leq kd​i​​≤k的最大的ii。于是时间复杂度就是\text{O}((n+m) \log n)O((n+m)logn).

///

#include<bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std ;
typedef long long ll;
#define mem(a) memset(a,0,sizeof(a))
#define pb push_back
inline ll read()
{
ll x=,f=;char ch=getchar();
while(ch<''||ch>''){
if(ch=='-')f=-;ch=getchar();
}
while(ch>=''&&ch<=''){
x=x*+ch-'';ch=getchar();
}return x*f;
}
//****************************************
const int N=+;
#define mod 1000000007
#define inf 10000007 int ind[N],head[N],t,n,m,K,vis[N];
vector<int > ans;
vector<int >G[N];
struct ss {
int l,r,sum,index;
}tr[N*];
struct sss {
int to,next;
}e[N*];
void init() {
t=;mem(head);mem(ind);ans.clear();mem(vis);
for(int i=;i<=n;i++)G[i].clear();
}
void add(int u,int v) {e[t].to=v;e[t].next=head[u];head[u]=t++;}
void build(int k,int s,int t) {
tr[k].l=s;tr[k].r=t;
if(s==t) {
tr[k].sum=ind[s];
tr[k].index=s;
return ;
}
int mid=(s+t)>>;
build(k<<,s,mid);
build(k<<|,mid+,t);
tr[k].sum=min(tr[k<<].sum,tr[k<<|].sum);
}
int ask(int k,int s,int t,int c) {
int ret;
if(tr[k].l==tr[k].r&&tr[k].l==s) {
return tr[k].index;
}
int mid=(tr[k].l+tr[k].r)>>;
if(tr[k<<|].sum<=c) {
ret=ask(k<<|,mid+,t,c);
}
else {
ret=ask(k<<,s,mid,c);
}
return ret;
}
void update(int k,int x,int c) {
if(tr[k].l==tr[k].r&&tr[k].l==x) {
tr[k].sum+=c;
return ;
}
int mid=(tr[k].l+tr[k].r)>>;
if(x<=mid) update(k<<,x,c);
else update(k<<|,x,c);
tr[k].sum=min(tr[k<<].sum,tr[k<<|].sum);
}
int main() { while(scanf("%d%d%d",&n,&m,&K)!=EOF) {
init();int u,v,check;
for( int i=;i<=m;i++) {
scanf("%d%d",&u,&v);
ind[v]++;
G[u].pb(v);
}
build(,,n);
for(int i=n;i>=;i--) {
check=ask(,,n,K);
ans.pb(check);
K-=ind[check];
update(,check,inf);
for(int j=;j<G[check].size();j++) {
update(,G[check][j],-);
ind[G[check][j]]--;
}
}
for(int i=;i<ans.size()-;i++) {
printf("%d ",ans[i]);
}
printf("%d\n",ans[ans.size()-]);
}
return ;
}

代码

HDU5195 线段树+拓扑的更多相关文章

  1. hdu5195 二分+线段树+拓扑序

    这题说的给了n个点m条边要求保证是一个有向无环图,可以删除至多k条边使得这个图的拓扑序的字典序最大,我们知道如果我们要排一个点的时候一定要考虑比他大的点是否可以.通过拆边马上拆出来,如果可以拆当然是拆 ...

  2. bzoj3276磁力 两种要求下的最大值:分块or线段树+拓扑

    进阶指南上的做法是分块的.. 但是线段树搞起来也挺快,将磁石按照距离排序,建立线段树,结点维护区间质量最小值的下标 进行拓扑,每次在可行的范围内在线段树中找到质量最小的下标取出,取出后再将线段树对应的 ...

  3. BZOJ4383 Pustynia(线段树+拓扑排序)

    线段树优化建图暴力拓扑排序即可.对于已确定的数,拓扑排序时dp,每个节点都尽量取最大值,如果仍与已确定值矛盾则无解.叶子连出的边表示大于号,其余边表示大于等于. #include<iostrea ...

  4. 【AtCoder Grand Contest 001F】Wide Swap [线段树][拓扑]

    Wide Swap Time Limit: 50 Sec  Memory Limit: 512 MB Description Input Output Sample Input 8 3 4 5 7 8 ...

  5. hdu 5195 DZY Loves Topological Sorting 线段树+拓扑排序

    DZY Loves Topological Sorting Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/sho ...

  6. HDU5638 / BestCoder Round #74 (div.1) 1003 Toposort 线段树+拓扑排序

    Toposort   问题描述 给出nn个点mm条边的有向无环图. 要求删掉恰好kk条边使得字典序最小的拓扑序列尽可能小. 输入描述 输入包含多组数据. 第一行有一个整数TT, 表示测试数据组数. 对 ...

  7. [CSP-S模拟测试]:Permutation(线段树+拓扑排序+贪心)

    题目描述 你有一个长度为$n$的排列$P$与一个正整数$K$你可以进行如下操作若干次使得排列的字典序尽量小对于两个满足$|i−j|\geqslant K$且$|P_i−P_j|=1$的下标$i$与$j ...

  8. [hdu5195]线段树

    题意:给一个DAG,最多可以删去k条边,求字典序最大的拓扑序列.思路:贪心选取当前可选的最大编号即可,同时用线段树维护下.一个节点可以被选,当且仅当没有指向它的边. #include <iost ...

  9. BZOJ3832[Poi2014]Rally——权值线段树+拓扑排序

    题目描述 An annual bicycle rally will soon begin in Byteburg. The bikers of Byteburg are natural long di ...

随机推荐

  1. 增加删除div

    <!doctype html><html><head><meta charset="utf-8"><title>无标题文 ...

  2. unity 旋转两种方法

    transform.Rotate(new Vector3(0, 10, 10)*speed*Time.deltaTime); // 物体绕x轴.y轴.z轴旋转 transform.RotateArou ...

  3. JS——回调函数

    1.回调函数作为参数的形式进行使用 2.回调函数一定程度上达到了解耦效果(模块化.功能化) <script> console.log(op(1, 2, add)); console.log ...

  4. Lazarus Coolbar and AnchroDocking

    在lazarus1.6里加载了AnchroDocking后,Coolbar突然不见了,找了好久没找到,原来在这里! 在AnchroDocking中可能是为了界面的最大化,默认是开始Toolbar 而关 ...

  5. zabbix配置邮件报警(第四篇)

    zabbix配置邮件报警(第四篇) 邮件报警可采用本地邮件服务,也可以自定义脚本,这里我采用本地邮件服务报警 添加收件人

  6. SpringMVC(四)@RequestParam

    使用@RequestParam可以将URL中的请求参数,绑定到方法的入参上,并通过@RequestParam的3个参数进行配置 Modifier and Type Optional Element D ...

  7. PHP连接mysql8.0出错“SQLSTATE[HY000] [2054] The server requested authentication method unkno…

    今天安装安装一个叫得推校园O2O系统的使劲都说连接不上服务器. 下面是安装说明,我直接进行3步骤,导入数据库配置文件,结果就显示题目报错的内容 安装说明: 直接输入程序目录即可 http://loca ...

  8. 无需编写代码,用接口管理工具 eoLinker 高效完成API测试流程相关业务

    引言 作为开发人员,有时需要协助市场部门进行开发,比如在市场推广中,经常通过给用户赠送优惠券来提高复购率.这篇文章,将介绍如何使用接口管理工具 eoLinker 的自动化测试 [UI模式] 构建此业务 ...

  9. 栈和队列问题:设计一个有 getMin 功能的栈

    [知识点] 栈是一个先进后出(FILO-First In Last Out)的数据结构,队列是一种先进先出(FIFO-First In First Out)的数据结构. [题目] 实现一个特殊的栈,在 ...

  10. ZOJ 3180 Number Game(模拟,倒推)

    题目 思路: 先倒推!到最后第二步,然后: 初始状态不一定满足这个状态.所以我们要先从初始状态构造出它出发的三种状态.那这三种状态跟倒推得到的状态比较即可. #include<stdio.h&g ...