[hdu5195]线段树

题意:给一个DAG,最多可以删去k条边,求字典序最大的拓扑序列。思路:贪心选取当前可选的最大编号即可,同时用线段树维护下。一个节点可以被选,当且仅当没有指向它的边。

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <algorithm>
  4 #include <cstring>
  5 #include <map>
  6 #include <queue>
  7 #include <cmath>
  8 #include <vector>
  9 #include <ctime>
 10 #include <cctype>
 11 
 12 using namespace std;
 13 
 14 #define mem0(a) memset(a, 0, sizeof(a))
 15 #define lson l, m, rt << 1
 16 #define rson m + 1, r, rt << 1 | 1
 17 #define define_m int m = (l + r) >> 1
 18 #define Rep(a, b) for(int a = 0; a < b; a++)
 19 #define lowbit(x) ((x) & (-(x)))
 20 #define constructInt3(name, a, b, c) name(int a = 0, int b = 0, int c = 0): a(a), b(b), c(c) {}
 21 #define constructInt2(name, a, b) name(int a = 0, int b = 0): a(a), b(b) {}
 22 
 23 typedef double db;
 24 typedef long long LL;
 25 
 26 const int dx[4] = {1, 0, -1, 0};
 27 const int dy[4] = {0, -1, 0, 1};
 28 const int maxn = 1e5 + 7;
 29 const int maxm = 1e5 + 7;
 30 const int MD = 1e9 +7;
 31 const int INF = 1e9 + 7;
 32 
 33 template<class edge> struct Graph {
 34     vector<vector<edge> > adj;
 35     Graph(int n) {adj.clear(); adj.resize(n + 5);}
 36     Graph() {adj.clear(); }
 37     void resize(int n) {adj.resize(n + 5); }
 38     void add(int s, edge e){adj[s].push_back(e);}
 39     void del(int s, edge e) {adj[s].erase(find(iter(adj[s]), e)); }
 40     vector<edge>& operator [](int t) {return adj[t];}
 41 };
 42 Graph<int> G, H;
 43 int X;
 44 struct Seg {
 45     int minv[maxn << 2];
 46     void build(int l, int r, int rt) {
 47         if (l == r) {
 48             minv[rt] = H[l].size();
 49             return ;
 50         }
 51         define_m;
 52         build(lson);
 53         build(rson);
 54         minv[rt] = min(minv[rt << 1], minv[rt << 1 | 1]);
 55     }
 56     void update(int p, int x, int l, int r, int rt) {
 57         if (l == r) {
 58             minv[rt] += x;
 59             return ;
 60         }
 61         define_m;
 62         if (p <= m) update(p, x, lson);
 63         else update(p, x, rson);
 64         minv[rt] = min(minv[rt << 1], minv[rt << 1 | 1]);
 65     }
 66     int get(int k, int l, int r, int rt) {
 67         if (l == r) {
 68             X = minv[rt];
 69             return l;
 70         }
 71         define_m;
 72         if (minv[rt << 1 | 1] <= k) return get(k, rson);
 73         return get(k, lson);
 74     }
 75 };
 76 Seg S;
 77 int main() {
 78     //freopen("in.txt", "r", stdin);
 79     int n, m, k;
 80     while (cin >> n >> m >> k) {
 81         G.adj.clear();
 82         G.resize(n);
 83         H.adj.clear();
 84         H.resize(n);
 85         for (int i = 0, u, v; i < m; i++) {
 86             scanf("%d%d", &u, &v);
 87             G.add(u, v);
 88             H.add(v, u);
 89         }
 90         S.build(1, n, 1);
 91         for (int i = n; i; i--) {
 92             int dot = S.get(k, 1, n, 1);
 93             k -= X;
 94             printf("%d%c", dot, i >= 2? ' ' : '
');
 95             S.update(dot, INF, 1, n, 1);
 96             for (int j = 0; j < G[dot].size(); j++) {
 97                 S.update(G[dot][j], -1, 1, n, 1);
 98             }
 99         }
100     }
101     return 0;
102 }
View Code
原文地址:https://www.cnblogs.com/jklongint/p/4419357.html