HDU5195 线段树+拓扑

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).

///1085422276

#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=0,f=1;char ch=getchar();
    while(ch<‘0‘||ch>‘9‘){
        if(ch==‘-‘)f=-1;ch=getchar();
    }
    while(ch>=‘0‘&&ch<=‘9‘){
        x=x*10+ch-‘0‘;ch=getchar();
    }return x*f;
}
//****************************************
const int  N=500000+50;
#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*5];
struct sss {
  int to,next;
}e[N*2];
void init() {
  t=1;mem(head);mem(ind);ans.clear();mem(vis);
  for(int i=1;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)>>1;
     build(k<<1,s,mid);
     build(k<<1|1,mid+1,t);
     tr[k].sum=min(tr[k<<1].sum,tr[k<<1|1].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)>>1;
    if(tr[k<<1|1].sum<=c) {
        ret=ask(k<<1|1,mid+1,t,c);
    }
    else  {
        ret=ask(k<<1,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)>>1;
     if(x<=mid) update(k<<1,x,c);
     else update(k<<1|1,x,c);
     tr[k].sum=min(tr[k<<1].sum,tr[k<<1|1].sum);
}
int main() {

    while(scanf("%d%d%d",&n,&m,&K)!=EOF) {
        init();int u,v,check;
        for( int i=1;i<=m;i++) {
            scanf("%d%d",&u,&v);
            ind[v]++;
            G[u].pb(v);
        }
        build(1,1,n);
        for(int i=n;i>=1;i--) {
            check=ask(1,1,n,K);
            ans.pb(check);
            K-=ind[check];
            update(1,check,inf);
            for(int j=0;j<G[check].size();j++) {
                update(1,G[check][j],-1);
                ind[G[check][j]]--;
            }
        }
        for(int i=0;i<ans.size()-1;i++) {
            printf("%d ",ans[i]);
        }
        printf("%d\n",ans[ans.size()-1]);
    }
  return 0;
}

代码

时间: 2025-01-06 01:45:20

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

bzoj 3832: [Poi2014]Rally(线段树+拓扑排序)

3832: [Poi2014]Rally Time Limit: 20 Sec  Memory Limit: 128 MBSec  Special Judge Submit: 113  Solved: 56 [Submit][Status][Discuss] Description An annual bicycle rally will soon begin in Byteburg. The bikers of Byteburg are natural long distance cyclis

hdu5195 DZY Loves Topological Sorting 线段树+拓扑排序

要求在一个DAG中删去不多于k条边,使得拓扑序的字典序最大. 贪心策略:每次删去入度小于res的,序号尽量大的点的入边. 需要用线段树维护区间最小值. 代码: #include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<queue> #include<algorithm> #include<vector> using name

hdu5195 二分+线段树+拓扑序

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

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

Toposort 问题描述 给出nn个点mm条边的有向无环图. 要求删掉恰好kk条边使得字典序最小的拓扑序列尽可能小. 输入描述 输入包含多组数据. 第一行有一个整数TT, 表示测试数据组数. 对于每组数据: 第一行包含3个整数nn, mm和kk (1 \le n \le 100000, 0 \le k \le m \le 200000)(1≤n≤100000,0≤k≤m≤200000), 表示图中结点数目, 图中边的数目以及要删的边数. 接下来mm行, 每行包含两个整数u_iu?i?? and

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

DZY Loves Topological Sorting Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5195 Description A topological sort or topological ordering of a directed graph is a linear ordering of its vertices such that for ev

[hdu5195]线段树

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

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

题目描述 你有一个长度为$n$的排列$P$与一个正整数$K$你可以进行如下操作若干次使得排列的字典序尽量小对于两个满足$|i−j|\geqslant K$且$|P_i−P_j|=1$的下标$i$与$j$,交换$P_i$与$P_j$ 输入格式 第一行包括两个正整数$n$与$K$第二行包括$n$个正整数,第$i$个正整数表示$P_i$ 输出格式 输出一个新排列表示答案输出共$n$行,第$i$行表示$P_i$ 样例 样例输入: 8 34 5 7 8 3 1 2 6 样例输出: 12675348 数据范

HDU 5195 DZY Loves Topological Sorting (拓扑排序+线段树)

题目地址:HDU 5195 简直受不了了..BC第二题都开始线段树+拓扑排序了... 这题很容易想到拓扑排序过程中贪心,但是贪心容易TLE,所以需要用数据结构去维护,我用的是线段树维护.每次找入度小于等于k的编号最大的点,这样就可以保证字典序一定是最大的. 代码如下: #include <iostream> #include <string.h> #include <math.h> #include <queue> #include <algorith

hdu 5195 DZY Loves Topological Sorting BestCoder Round #35 1002 [ 拓扑排序 + 优先队列 || 线段树 ]

传送门 DZY Loves Topological Sorting Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 221    Accepted Submission(s): 52 Problem Description A topological sort or topological ordering of a directed