[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? ' ' : '\n');

 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

 

你可能感兴趣的:(HDU)