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. JQuery中常用的$.get(),$.post(),$.ajax(),$.getJSON(),load()的详解与区别

    背景:因为最近需要获取本地的数据件进行项目测试,需要用到JQuery实现数据文件的读取,但是由于对JQuery内的获取文件方式不太了解,这次趁着机会进行一下总结.因为该总结是本人根据平常的使用及网上的 ...

  2. 【GAN学习笔记】对抗式生成网络入门

    今天观看学习了一下台大李宏毅所讲授的 <Introduction of Generative Adversarial Network (GAN)>,对GAN有了一个初步的了解. GAN的基 ...

  3. CSS——background综合运用

    搜索栏图标: <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> < ...

  4. [Windows Server 2008] IIS自带FTP配置方法

    ★ 欢迎来到[护卫神·V课堂],网站地址:http://v.huweishen.com★ 护卫神·V课堂 是护卫神旗下专业提供服务器教学视频的网站,每周更新视频.★ 本节我们将带领大家:IIS自带FT ...

  5. 查看APK包名签名等信息

    有些游戏第三方比如分享需要配置游戏包名和签名,不同渠道包名签名又不同,所以时常需要查看不同apk包等签名信息,之前是使用等微博开放平台的手机客户端查看apk签名,前提是知道包名,网上找了下查看签名和包 ...

  6. js 时间 Fri Dec 12 2014 08:00:00 GMT+0800

    第一种var d = new Date('Fri Dec 12 2014 08:00:00 GMT+0800'); ) + '-' + d.getDate() + ' ' + d.getHours() ...

  7. ubuntu下查看如何配置pycharm

    ubuntu中PyCharm的安装与卸载 https://blog.csdn.net/weixin_31484477/article/details/81133590 pycharm ModuleNo ...

  8. centos7安装个人网盘owncloud

    现在个人资料越来越重要,网络速度也已经满足日常需要,网盘已经是生活着存取个人数据不可缺少的工具. 下面在linxu centos7下面安装owncloud搭建自己私人网盘: 1.新建一个账号用来安装个 ...

  9. 【转】resultMap详解(包含多表查询)

    简介: MyBatis的每一个查询映射的返回类型都是ResultMap,只是当我们提供的返回类型属性是resultType的时候,MyBatis对自动的给我们把对应的值赋给resultType所指定对 ...

  10. VMware Workstation 15 安装教程

    注:操作系统必须是64位    软件:360软件管家获取 1.运行下载完成的Vmware Workstation虚拟机软件包. 虚拟机软件的安装向导初始界面 2.在虚拟机软件的安装向导界面单击“下一步 ...