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. ansible 显示运行时间

    #独家秘诀cd /etc/ansible mkdir callback_plugins cd callback_plugins wget https://raw.githubusercontent.c ...

  2. 实现X*N

    #include<iostream> using namespace std; double foo(int n,double x) { if(1==n) { return x; } el ...

  3. H5 标签属性、input属性

    高亮文字: 全部商品只要<mark>6.18</mark> 结果:     加拼音文字: <ruby>變<rt>bian</rt></ ...

  4. JS——筋斗云案例

    需求: 1.鼠标移动到哪里,云彩移动到哪里 2.鼠标离开,云彩回到原点 3.鼠标离开,云彩回到之前点击的地方 <!DOCTYPE html> <html lang="en& ...

  5. CNN结构:图片风格分类效果已成(StyleAI)

    CNN结构:图片风格分类效果已成.可以在色彩空间对图片风格进行分类,并进行目标分类. StyleAI构架:FasterRCnn + RandomTrees 为何不使用MaskRCNN? MaskRCN ...

  6. 【sqli-labs】 less59 GET -Challenge -Double Query -5 queries allowed -Variation2 (GET型 挑战 双查询 只允许5次查询 变化2)

    整型的注入 http://192.168.136.128/sqli-labs-master/Less-59/?id=1 or UpdateXml(1,concat(0x7e,database(),0x ...

  7. 关于python中的property

    python中的property在类实例化的时候 可以把类方法变成类属性使用, 还可以用在简化赋值上 1)不用property的时候,你的类可能是这样写的 2)用propery的时候你可能会这样写,调 ...

  8. GCD & Operation queues & Thread

    One of the technologies for starting tasks asynchronously is Grand Central Dispatch (GCD). This tech ...

  9. VMware Workstation Pro 15 for Windows下载与安装

    VMware Workstation Pro 15 for Windows下载与安装 一.下载 下载地址:https://my.vmware.com/cn/web/vmware/details?dow ...

  10. python开发 面试题

    一.简述列表与元组的区别 答: 元组tuple与列表List相同点 元组tuple与列表List都是序列类型的容器对象,可以存放任何类型的数据.支持切片.迭代等操作. 元组tuple与列表List区别 ...