http://acm.hdu.edu.cn/showproblem.php?pid=5195
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.
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) .
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 2HintCase 1. Erase the edge (2->3),(4->5). And the lexicographically largest topological ordering is (5,3,1,2,4).
/**
hdu5195 线段树
题目大意:给定一个有向无环图,让你去掉p条边后找出字典序最大的一个拓扑排序数列
解题思路:若要满足字典序最大则靠前面的点值越大越好,用线段树维护区间入度最小值,每次查询找出满足入度小于当前q值的最大的点,然后输出,
更新所有以该点为起点的点的入度,复杂度O((n+m)logn).
官方题解:
因为我们要求最后的拓扑序列字典序最大,所以一定要贪心地将标号越大的点越早入队。我们定义点i的入度为di。假设当前还能删去k条边,
那么我们一定会把当前还没入队的di≤k的最大的i找出来,把它的di条入边都删掉,然后加入拓扑序列。可以证明,这一定是最优的。具体实
现可以用线段树维护每个位置的di,在线段树上二分可以找到当前还没入队的di≤k的最大的i。于是时间复杂度就是O((n+m)logn).
*/
#include <stdio.h>
#include <algorithm>
#include <iostream>
#include <string.h>
#include <vector>
using namespace std;
const int inf=0x3f3f3f3f;
const int maxn=100010;
int n,m,p,key;
int du[maxn];
vector<int>vec[maxn];
struct note
{
int x,l,r;
}edge[maxn*4];
void build(int l,int r,int root)
{
edge[root].l=l;
edge[root].r=r;
if(l==r)
{
edge[root].x=du[l];
return;
}
int mid=(l+r)/2;
build(l,mid,root<<1);
build(mid+1,r,root<<1|1);
edge[root].x=min(edge[root<<1].x,edge[root<<1|1].x);
}
void update(int x,int root)
{
if(edge[root].l==edge[root].r)
{
edge[root].x--;
return;
}
int mid=(edge[root].l+edge[root].r)/2;
if(x<=mid)
{
update(x,root<<1);
}
else
{
update(x,root<<1|1);
}
edge[root].x=min(edge[root<<1].x,edge[root<<1|1].x);
}
void query(int root)
{
if(edge[root].r==edge[root].l)
{
p-=edge[root].x;
key=edge[root].r;
edge[root].x=inf;
return;
}
if(edge[root<<1|1].x<=p)
{
query(root<<1|1);
}
else
{
query(root<<1);
}
edge[root].x=min(edge[root<<1].x,edge[root<<1|1].x);
}
int main()
{
while(~scanf("%d%d%d",&n,&m,&p))
{
memset(du,0,sizeof(du));
for(int i=0;i<m;i++)
{
int u,v;
scanf("%d%d",&u,&v);
vec[u].push_back(v);
du[v]++;
}
build(1,n,1);
for(int i=1;i<=n;i++)
{
query(1);
printf(i==n?"%d\n":"%d ",key);
update(key,1);
for(int j=0;j<vec[key].size();j++)
{
int x=vec[key][j];
update(x,1);
}
}
}
return 0;
}<span style="font-size: 1px; font-family: 'Courier New', Courier, monospace; white-space: pre-wrap;"> </span>