hdu.5195.DZY Loves Topological Sorting(topo排序 && 贪心)

DZY Loves Topological Sorting

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 866    Accepted Submission(s): 250

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 (uv) 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. (TestCase5) The first line, three integers n,m,k(1n,m105,0km). Each of the next m lines has two integers: u,v(uv,1u,vn), representing a direct edge(uv).
 

 

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
 
 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<queue>
 4 using namespace std;
 5 const int M = 100005 ;
 6 struct Edge
 7 {
 8     int v , nxt ;
 9     Edge () {}
10     Edge (int v , int nxt) : v (v) , nxt (nxt) {}
11 }e[M];
12 int H[M] , E ;
13 bool vis[M] ;
14 int ans[M] , top ;
15 int in[M] ;
16 int n , m , k ;
17 int u , v ;
18 inline int read () {
19     int ans = 0; char c; bool flag = false;
20     while ((c = getchar()) == ' ' || c == '\n' || c == '\r');
21     if (c == '-') flag = true; else ans = c - '0';
22     while ((c = getchar()) >= '0' && c <= '9') ans = ans * 10 + c - '0';
23     return ans * (flag ? -1 : 1);
24 }
25 
26 void addedge ()
27 {
28     e[E] = Edge ( v , H[u] ) ;
29     H[u] = E ++ ;
30 }
31 
32 void init ()
33 {
34     E = 0 ;
35     top = 0 ;
36     memset (H , - 1 , sizeof(H)) ;
37     memset (ans , 0 , sizeof(ans) ) ;
38     memset (in , 0 , sizeof(in)) ;
39     memset (vis , 0 , sizeof(vis) ) ;
40 }
41 
42 void topo ()
43 {
44     priority_queue <int> q ;
45     while (!q.empty ()) q.pop () ;
46     for (int i = 1 ; i <= n ; i++) if (in[i] == 0 && !vis[i]) q.push (i) ;
47     while ( !q.empty () ) {
48         int u = q.top () ;
49         q.pop () ;
50         ans[top ++] = u ;
51         for (int i = H[u] ; ~ i ; i = e[i].nxt) {
52             in[e[i].v] -- ;
53             if (in[e[i].v] == 0 && !vis[e[i].v])    q.push (e[i].v) ;
54         }
55     }
56 }
57 
58 void solve ()
59 {
60     init () ;
61     while (m--) {
62         u = read () , v = read () ;
63         addedge () ;
64         in[v] ++ ;
65     }
66     priority_queue <int> q ;
67     for (int i = 1 ; i <= n ; i++)  if (in[i] <= k) q.push (i) ;
68     while ( !q.empty () ) {
69         u = q.top () ;
70         q.pop () ;
71         if (in[u] > k) continue ;
72         ans[top ++] = u ;
73         k -= in[u] ;
74         vis[u] = 1 ;
75         for (int i = H[u] ; ~ i ; i = e[i].nxt) {
76            in[e[i].v] -- ;
77            if (in[e[i].v] <= k && !vis[u] ) q.push (e[i].v) ;
78         }
79     }
80     topo () ;
81     for (int i = 0 ; i < top ; i++) {
82         printf ("%d%c" , ans[i] , i == top - 1 ? '\n' : ' ') ;
83     }
84 }
85 
86 int main ()
87 {
88    // freopen ("a.txt" , "r" , stdin ) ;
89     while (~ scanf ("%d%d%d" , &n , &m , &k)) {
90         solve () ;
91     }
92     return 0 ;
93 }
View Code

用邻接表优化后,topo的时间复杂度O(n),空间复杂度也大大减少。orz。
还有快速读入。

托它们的福,这道题让我530ms过了。233333333

posted @ 2015-04-05 13:47  92度的苍蓝  阅读(211)  评论(0编辑  收藏  举报
http://images.cnblogs.com/cnblogs_com/Running-Time/724426/o_b74124f376fc157f352acc88.jpg