题目链接:
hdu:http://acm.hdu.edu.cn/showproblem.php?pid=5195
bc(中文):http://bestcoder.hdu.edu.cn/contests/contest_chineseproblem.php?cid=573&pid=1002
代码:
1 #include<algorithm> 2 #include<iostream> 3 #include<cstring> 4 #include<cstdio> 5 #include<vector> 6 #include<queue> 7 using namespace std; 8 9 const int maxn = 1e5 + 10; 10 const int INF = 0x3f3f3f3f; 11 12 int n, m, k; 13 14 struct Node { 15 int v, flag; 16 Node(int v,int flag=0):v(v),flag(flag){} 17 Node() { flag = 0; } 18 }; 19 20 vector<Node> head[maxn]; 21 int ind[maxn],done[maxn]; 22 23 void init() { 24 for (int i = 0; i < n; i++) { 25 ind[i] = done[i]=0; 26 head[i].clear(); 27 } 28 } 29 30 int main() { 31 while (scanf("%d%d%d", &n, &m, &k) == 3 && n) { 32 init(); 33 for (int i = 0; i < m; i++) { 34 int u, v; 35 scanf("%d%d", &u, &v); u--, v--; 36 ind[v]++; 37 head[u].push_back(Node(v,0)); 38 } 39 40 priority_queue<int> pq; 41 42 //删边 43 for (int i = n - 1; i >= 0; i--) { 44 if (k >= ind[i]) { 45 //将i的父亲ui中,满足ui<i,即边(ui,i)删了,这里要注意,对于边(ui,i),ui>i的边,根本不用删 46 k -= ind[i]; 47 pq.push(i); 48 for (int j = 0; j < head[i].size(); j++) { 49 Node &nd = head[i][j]; 50 if (i > nd.v) { 51 //把边(i,v)删了,拓扑排序的时候不能再走这条边了 52 nd.flag = 1; 53 ind[nd.v]--; 54 } 55 } 56 } 57 } 58 59 vector<int> ans; 60 //拓扑排序 61 while (!pq.empty()) { 62 int u = pq.top(); pq.pop(); 63 if (done[u]) continue; 64 ans.push_back(u); 65 done[u] = 1; 66 for (int i = 0; i < head[u].size(); i++) { 67 Node& nd = head[u][i]; 68 if (done[nd.v]||nd.flag) continue; 69 ind[nd.v]--; 70 if (ind[nd.v] == 0) pq.push(nd.v); 71 } 72 } 73 74 printf("%d", ans[0]+1); 75 for (int i = 1; i < ans.size(); i++) printf(" %d", ans[i]+1); 76 printf("\n"); 77 } 78 return 0; 79 } 80 /* 81 5 3 1 82 4 3 83 1 3 84 3 2 85 86 5 3 0 87 4 3 88 1 3 89 3 2 90 */
时间: 2024-10-07 23:46:59