zoukankan      html  css  js  c++  java
  • Kruskal重构树

    大意:

      Kruskal重构树即是将正常Kruskal算法中的最小生成树的边当作点,连接两个点集,且满足大(小)根堆性质,那么求两点间经过路径长度最值即它们的LCA的点权。

    证明:

      对于两个集合,它们之间的路径最值即连通这两个集合的最值边,且边已经过排序,故显然满足条件。

      证毕。


    经典用法:

      · 求两点间路径最小(大)值的最大(小)值。

      · 求当前点出发,仅经过边权小(大)于等于x的边可到达的所有点。

      那么求出点权最小(大)的那个代表边的节点,答案为其子树。

    例题:

      洛谷 - Problem 4197 - Peaks

      (在线)Krusal重构树 + 主席树

      

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <algorithm>
      5 #include <cmath>
      6 
      7 using namespace std;
      8 
      9 const int MAXN = 1e05 + 10;
     10 const int MAXM = 5e05 + 10;
     11 const int MAXT = (MAXN << 4) + (MAXN << 2);
     12 
     13 const int INF = 0x7fffffff;
     14 
     15 struct LinkedForwardStar {
     16     int to;
     17     
     18     int next;
     19 } ;
     20 
     21 LinkedForwardStar Link[MAXM << 2];
     22 int Head[MAXN << 1]= {0};
     23 int size = 0;
     24 
     25 void Insert (int u, int v) {
     26     Link[++ size].to = v;
     27     Link[size].next = Head[u];
     28     
     29     Head[u] = size;
     30 }
     31 
     32 int Root;
     33 
     34 int N, M, Q;
     35 
     36 int Height[MAXN];
     37 
     38 struct Line {
     39     int u, v;
     40     int w;
     41     
     42     Line () {}
     43     
     44     Line (int fu, int fv, int fw) :
     45         u (fu), v (fv), w (fw) {}
     46     
     47     bool operator < (const Line& p) const {
     48         return w < p.w;
     49     }
     50 } ;
     51 
     52 Line Edges[MAXM];
     53 
     54 int Ances[MAXN << 1];
     55 
     56 int Find (int x) {
     57     return x == Ances[x] ? x : Ances[x] = Find (Ances[x]);
     58 }
     59 
     60 int nodes;
     61 
     62 int Val[MAXN << 1];
     63 
     64 void Kruskal () {
     65     for (int i = 1; i <= N; i ++)
     66         Ances[i] = i;
     67     
     68     sort (Edges + 1, Edges + M + 1);
     69     
     70     for (int i = 1; i <= M; i ++) {
     71         int u = Edges[i].u;
     72         int v = Edges[i].v;
     73         int w = Edges[i].w;
     74         
     75         int fu = Find (u);
     76         int fv = Find (v);
     77         
     78         if (fu == fv)
     79             continue;
     80         
     81         int newnode = ++ nodes;
     82         Val[newnode] = w;
     83         Ances[newnode] = Ances[fu] = Ances[fv] = nodes;
     84         Insert (newnode, fu), Insert (fu, newnode);
     85         Insert (newnode, fv), Insert (fv, newnode);
     86     }
     87 }
     88 
     89 int Father[MAXN << 1][30];
     90 
     91 int Belong[MAXN];
     92 int dfsord = 0; 
     93 
     94 int fSize[MAXN << 1];
     95 int Minleft[MAXN << 1], Maxright[MAXN << 1];
     96 
     97 bool Vis[MAXN << 1]= {false};
     98 
     99 void DFS (int root, int father) {
    100     Vis[root] = true;
    101     fSize[root] = 0;
    102     Minleft[root] = INF, Maxright[root] = 0;
    103     Father[root][0] = father;
    104     for (int j = 1; j <= 20; j ++) {
    105         if (! Father[root][j - 1])
    106             continue;
    107         
    108         Father[root][j] = Father[Father[root][j - 1]][j - 1];
    109     }
    110     
    111     int cnt = 0;
    112     for (int i = Head[root]; i; i = Link[i].next) {
    113         int v = Link[i].to;
    114         
    115         if (v == father)
    116             continue;
    117         
    118         DFS (v, root);
    119         
    120         cnt ++;
    121         fSize[root] += fSize[v];
    122         Minleft[root] = min (Minleft[root], Minleft[v]);
    123         Maxright[root] = max (Maxright[root], Maxright[v]);
    124     }
    125     
    126     if (! cnt) {
    127         Belong[++ dfsord] = root;
    128         
    129         fSize[root] = 1;
    130         Minleft[root] = dfsord;
    131         Maxright[root] = dfsord;
    132     }
    133 }
    134 
    135 int Findpos (int u, int minval) {
    136     for (int j = 20; j >= 0; j --)
    137         if (Father[u][j] && Val[Father[u][j]] <= minval)
    138             u = Father[u][j];
    139     
    140     return u;
    141 }
    142 
    143 int Mapping[MAXN];
    144 int sizemapp = 0;
    145 
    146 int ChiefTree[MAXT];
    147 int treenode = 0;
    148 
    149 int Left[MAXT], Right[MAXT];
    150 int Size[MAXT];
    151 
    152 int Build (int left, int right) {
    153     int root = ++ treenode;
    154     
    155     Size[root] = 0;
    156     
    157     if (left == right)
    158         return root;
    159     
    160     int mid = (left + right) >> 1;
    161     
    162     Left[root] = Build (left, mid);
    163     Right[root] = Build (mid + 1, right);
    164     
    165     return root;
    166 }
    167 
    168 int Modify (int pre, int left, int right, int pos) {
    169     int root = ++ treenode;
    170     
    171     Left[root] = Left[pre], Right[root] = Right[pre];
    172     Size[root] = Size[pre] + 1;
    173     
    174     if (left == right)
    175         return root;
    176     
    177     int mid = (left + right) >> 1;
    178     
    179     if (pos <= mid)
    180         Left[root] = Modify (Left[pre], left, mid, pos);
    181     else
    182         Right[root] = Modify (Right[pre], mid + 1, right, pos);
    183     
    184     return root;
    185 }
    186 
    187 int Query (int Sl, int Sr, int left, int right, int k) {
    188     if (left == right)
    189         return Mapping[left];
    190     
    191     int psize = Size[Right[Sr]] - Size[Right[Sl]];
    192     
    193     int mid = (left + right) >> 1;
    194     
    195     if (psize >= k)
    196         return Query (Right[Sl], Right[Sr], mid + 1, right, k);
    197     else
    198         return Query (Left[Sl], Left[Sr], left, mid, k - psize);
    199 }
    200 
    201 int main () {
    202     scanf ("%d%d%d", & N, & M, & Q);
    203     nodes = N;
    204     
    205     for (int i = 1; i <= N; i ++) {
    206         scanf ("%d", & Height[i]);
    207         Mapping[++ sizemapp] = Height[i];
    208     }
    209     
    210     sort (Mapping + 1, Mapping + sizemapp + 1);
    211     sizemapp = unique (Mapping + 1, Mapping + sizemapp + 1) - Mapping - 1;
    212     
    213     for (int i = 1; i <= M; i ++) {
    214         int u, v, w;
    215         scanf ("%d%d%d", & u, & v, & w);
    216         
    217         Edges[i] = Line (u, v, w);
    218     }
    219     
    220     Kruskal ();
    221     
    222     for (int i = 1; i <= nodes; i ++)
    223         if (! Vis[i]) {
    224             Root = Find (i);
    225             DFS (Root, 0);
    226         }
    227     
    228     ChiefTree[0] = Build (1, sizemapp);
    229     for (int i = 1; i <= dfsord; i ++) {
    230         int pos = lower_bound (Mapping + 1, Mapping + sizemapp, Height[Belong[i]]) - Mapping;
    231         ChiefTree[i] = Modify (ChiefTree[i - 1], 1, sizemapp, pos);
    232     }
    233     
    234     for (int Case = 1; Case <= Q; Case ++) {
    235         int from, minval, k;
    236         scanf ("%d%d%d", & from, & minval, & k);
    237         
    238         int maxpos = Findpos (from, minval);
    239         if (fSize[maxpos] < k) {
    240             puts ("-1");
    241             continue;
    242         }
    243         
    244         int ans = Query (ChiefTree[Minleft[maxpos] - 1], ChiefTree[Maxright[maxpos]], 1, sizemapp, k);
    245         
    246         printf ("%d
    ", ans);
    247     }
    248     
    249     return 0;
    250 }
    251 
    252 /*
    253 10 11 4
    254 1 2 3 4 5 6 7 8 9 10
    255 1 4 4
    256 2 5 3
    257 9 8 2
    258 7 8 10
    259 7 1 4
    260 6 7 1
    261 6 4 8
    262 2 1 5
    263 10 8 10
    264 3 4 7
    265 3 4 6
    266 1 5 2
    267 1 5 6
    268 1 5 8
    269 8 9 2
    270 */
    View Code

      

  • 相关阅读:
    正则
    cookie、sesion
    POJ-1509
    HDU-3374
    ZOJ-3822
    HDU-5492
    在什么情况下Java比C++快?
    HDU-5451
    SPOJ-913
    莫比乌斯反演入门
  • 原文地址:https://www.cnblogs.com/Colythme/p/9703339.html
Copyright © 2011-2022 走看看