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

Input
The input consists several test cases. (
TestCase≤5
)
The first line, three integers n,m,k(1≤n,m≤10
5
,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≤10



Each of the next m



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).
Source
Recommend
http://bestcoder.hdu.edu.cn/
Problem B - DZY Loves Topological Sorting 因為我們要求最后的拓撲序列字典序最大,所以一定要貪心地將標號越大的點越早入隊。我們定義點i的入度為di。假設當前還能刪去k條邊,那么我們一定會把當前還沒入隊的di≤k的最大的i找出來,把它的di條入邊都刪掉,然后加入拓撲序列。可以證明,這一定是最優的。 具體實現可以用線段樹維護每個位置的di,在線段樹上二分可以找到當前還沒入隊的di≤k的最大的i。於是時間復雜度就是O((n+m)logn).
不過,這里面說的還有一點不太清楚,
轉一下另一個題解:
http://blog.csdn.net/glqac/article/details/44710897
看題意以為是個拓撲排序。事實上,就是個線段樹。因為最多可以刪k條邊, 所以就是在線段樹里找入度小於等於k的最大值,那么保存個區間最小就ok了。如果右子樹的區間最小小於等於k那么就往右邊走,因為是要找字典序最大的。當k是0,也是這樣找,就跟topological sort是一樣的。然后刪除一個點就在線段樹那個點置最大值,再刪除他的邊。因為總共也就m條邊不超過10^5。
總復雜度o(n+m)logn。
我的解法:
用優先隊列,當前節點的入度小於k便入隊列,出隊列時以節點編號為優先權,如果小於等於k,則輸出,反之,跳過。不過寫的時候遇到幾個問題:
1.節點重復入隊列沒事,但是,不能讓已經在隊列中的再入隊列。故要用vis,vis=0暫時不在隊列中,vis=-1,在隊列中,vis=1,已經輸出。
2.判斷隊首元素的入度是否 小於k時,要用現在的入度,而不是入隊列時的入度,因為,可能在處理其它點的時候,該點的入度已經發生了變化。
總的來說,還是線段樹的方法思路清晰~~
13278084 | 2015-03-29 08:49:19 | Accepted | 5195 | 561MS | 6988K | 2158 B | C++ | czy |
13278083 | 2015-03-29 08:49:04 | Time Limit Exceeded | 5195 | 2000MS | 8308K | 2158 B | G++ | czy |
1 #include <cstdio> 2 #include <cstring> 3 #include <stack> 4 #include <vector> 5 #include <map> 6 #include <algorithm> 7 #include <queue> 8 9 #define ll long long 10 int const N = 100005; 11 int const M = 205; 12 int const inf = 1000000000; 13 ll const mod = 1000000007; 14 15 using namespace std; 16 17 int n,m; 18 int k; 19 int vis[N]; 20 vector<int> bian[N]; 21 int r[N]; 22 23 struct node 24 { 25 friend bool operator < (node n1,node n2) 26 { 27 return n1.index < n2.index; 28 } 29 int index; 30 int d; 31 }; 32 33 void ini() 34 { 35 int u,v; 36 memset(r,0,sizeof(r)); 37 memset(vis,0,sizeof(vis)); 38 int i; 39 for(i=0;i<=n;i++){ 40 bian[i].clear(); 41 } 42 for(i=1;i<=m;i++){ 43 scanf("%d%d",&u,&v); 44 r[ v ]++; 45 bian[ u ].push_back( v ); 46 } 47 48 } 49 50 void solve() 51 { 52 node te,nt; 53 int i; 54 priority_queue<node> que; 55 for(i=n;i>=1;i--){ 56 if(r[ i ]<=k){ 57 te.index=i; 58 te.d=r[i]; 59 que.push(te); 60 vis[i]=-1; 61 } 62 } 63 64 int ff=0; 65 vector<int>::iterator it; 66 while(que.size()>=1){ 67 te=que.top(); 68 que.pop(); 69 // printf(" \nu=%d r=%d k=%d\n",te.index,te.d,k); 70 if(r[te.index]<=k){ 71 k-=r[te.index]; 72 vis[te.index]=1; 73 } 74 else{ 75 vis[te.index]=0; 76 continue; 77 } 78 if(ff==0){ 79 ff=1; 80 printf("%d",te.index); 81 } 82 else{ 83 printf(" %d",te.index); 84 } 85 for(it=bian[te.index].begin();it!=bian[te.index].end();it++) 86 { 87 int y=*it; 88 r[y]--; 89 if(r[y]<=k && vis[y]==0){ 90 nt.index=y; 91 nt.d=r[y]; 92 que.push(nt); 93 vis[y]=-1; 94 } 95 } 96 } 97 printf("\n"); 98 } 99 100 void out() 101 { 102 103 } 104 105 int main() 106 { 107 //freopen("data.in","r",stdin); 108 //freopen("data.out","w",stdout); 109 //scanf("%d",&T); 110 //for(int cnt=1;cnt<=T;cnt++) 111 //while(T--) 112 while(scanf("%d%d%d",&n,&m,&k)!=EOF) 113 { 114 ini(); 115 solve(); 116 out(); 117 } 118 }