zoukankan      html  css  js  c++  java
  • HDU4409-LCA模拟

    给一个家谱,回答给的操作结果。

      1)L 按照字典序排序儿子,输出整个家谱。

      2)b 求出所给name的所有兄弟。

      3)c 求出两个name的LCA

    读入数据时,我用一个curfather数组维护固定深度的爸爸,之后就可以方便的将所给的数据形式转换成邻接表建图,同时使用map存储name和id号。Tree结构体数组存储每个人的信息,父亲,儿子(vector存储,方便排序等操作),name,深度。

    L操作将每个人的儿子排序,递归打印。

    b操作直接找到他父亲,用size函数计算儿子数。

    c操作用st表+DFS在线求解。

    这道题还有两个坑,根的兄弟要输出1,a和b的lca是a或b时,所求为其lca的父亲。

    还有就是递归打印会暴栈,要交C++用黑科技的扩栈语句。

    //这个题用了我好久,先学LCA,再纠结怎么处理输入数据,立下不a出来不吃饭的flag,最终a了。。

      1 #include <algorithm>
      2 #include <iostream>
      3 #include <cstring>
      4 #include <ctype.h>
      5 #include <cstdlib>
      6 #include <cstdio>
      7 #include <vector>
      8 #include <string>
      9 #include <queue>
     10 #include <stack>
     11 #include <cmath>
     12 #include <set>
     13 #include <map>
     14 #pragma comment(linker,"/STACK:102400000,102400000")
     15 
     16 using namespace std;
     17 
     18 const int maxn = 300100;
     19 int N,M,T,rmq[2*maxn];
     20 
     21 struct ST
     22 {
     23     int stTable[2*maxn][20];
     24     int prelog2[2*maxn];
     25 
     26     void init(int n)
     27     {
     28         prelog2[1] = 0;stTable[1][0] = 1;
     29         for(int i=2;i <= n;i++)
     30         {
     31             prelog2[i] = prelog2[i-1];
     32             stTable[i][0] = i;
     33             if((1 << (prelog2[i]+1)) == i) ++prelog2[i];
     34         }
     35         for(int i=n;i > 0;i--)
     36         {
     37             for(int j=1;(i+(1<<j)-1) < n;j++)
     38             {
     39                 stTable[i][j] = rmq[stTable[i][j-1]] < rmq[stTable[i+(1<<(j-1))][j-1]] ? stTable[i][j-1] : stTable[i+(1<<(j-1))][j-1];
     40             }
     41         }
     42     }
     43 
     44     int query(int a,int b)
     45     {
     46         if(a > b) swap(a,b);
     47         int k = prelog2[b-a+1];
     48         return rmq[stTable[a][k]] < rmq[stTable[b-(1<<k)+1][k]] ? stTable[a][k] : stTable[b-(1<<k)+1][k];
     49     }
     50 };
     51 
     52 struct Node
     53 {
     54     int to,next;
     55 };
     56 
     57 struct LCA
     58 {
     59     int n;
     60     Node edge[2*maxn];
     61     int tol,head[maxn],Dfs[2*maxn],P[maxn],cnt;
     62     bool vis[maxn];
     63     ST st;
     64 
     65     void init(int n)
     66     {
     67         this->n = n;
     68         tol = 0;
     69         memset(head,-1,sizeof head);
     70     }
     71 
     72     void add_edge(int a,int b)
     73     {
     74         edge[tol].to = b;
     75         edge[tol].next = head[a];
     76         head[a] = tol++;
     77         edge[tol].to = a;
     78         edge[tol].next = head[b];
     79         head[b] = tol++;
     80     }
     81 
     82     int query(int a,int b)
     83     {
     84         //printf("%d %d:%d
    ",P[a],P[b],st.query(P[a],P[b]));
     85         return Dfs[st.query(P[a],P[b])];
     86     }
     87 
     88     void dfs(int a,int deepth)
     89     {
     90         vis[a] = true;
     91         ++cnt;
     92         Dfs[cnt] = a;
     93         rmq[cnt] = deepth;
     94         P[a] = cnt;
     95         //printf("cnt=%d
    ",cnt);
     96         for(int i = head[a];i != -1;i = edge[i].next)
     97         {
     98             int v = edge[i].to;
     99             if(vis[v]) continue;
    100             dfs(v,deepth+1);
    101             ++cnt;
    102             Dfs[cnt] = a;
    103             rmq[cnt] = deepth;
    104         }
    105     }
    106 
    107     void solve(int root)
    108     {
    109         memset(vis,false,sizeof vis);
    110         cnt = 0;
    111         //printf("root=%d
    ",root);
    112         dfs(root,0);
    113         st.init(2*n-1);
    114     }
    115 
    116 }lca;
    117 
    118 int num = 0;
    119 int curfather[maxn];
    120 struct Node_son
    121 {
    122     int deepth;
    123     int fa;
    124     vector<int> son;
    125     string name;
    126 }Tree[maxn];
    127 
    128 bool cmpson(const int a,const int b) { return Tree[a].name < Tree[b].name;}
    129 
    130 void Print_Tree(int root)
    131 {
    132     for(int i=0;i<Tree[root].deepth;i++) cout << '.';
    133     cout << Tree[root].name << endl;
    134     if(Tree[root].son.empty()) return;
    135     sort(Tree[root].son.begin(),Tree[root].son.end(),cmpson);
    136 
    137     for(int i=0;i < (int)Tree[root].son.size();i++)
    138     {
    139         Print_Tree(Tree[root].son[i]);
    140     }
    141 }
    142 
    143 int main()
    144 {
    145     while(cin>>N && N)
    146     {
    147         lca.init(N);
    148         map <string ,int > m;
    149         memset(curfather,0,sizeof curfather);
    150 
    151         for(int i=0;i<N;i++)
    152         {
    153             cin>>Tree[i].name;
    154             Tree[i].son.clear();
    155             int lev = 0;
    156             for(int t = 0;t < (int)Tree[i].name.size();t++)    
    157             {
    158                 if(Tree[i].name[t] != '.') break;
    159                 else lev++;
    160             }
    161             Tree[i].name.erase(Tree[i].name.begin(),Tree[i].name.begin()+lev);
    162             m.insert(pair<string,int>(Tree[i].name,i));
    163             Tree[i].deepth = lev;
    164 
    165             curfather[lev+1] = i;
    166             if(lev == 0) continue; 
    167             Tree[i].fa = curfather[lev];
    168             Tree[Tree[i].fa].son.push_back(i);
    169             lca.add_edge(Tree[i].fa+1,i+1);
    170         }
    171         string op;cin >> T;
    172         lca.solve(1);
    173 
    174         while(T--)
    175         {
    176             cin >> op;
    177             if(op[0] == 'L')       //重构树,字典序
    178             {
    179                 Print_Tree(0);
    180             }
    181             else if(op[0] == 'b')  //兄弟数
    182             {
    183                 string son;
    184                 cin >> son;
    185                 if(son == Tree[0].name) cout << 1 <<endl;
    186                 else cout << Tree[ Tree[m[son]].fa ].son.size()<<endl;
    187             }
    188             else if(op[0] == 'c')  //LCA DFS+ST
    189             {
    190                 string son1,son2;
    191                 cin >> son1 >> son2;
    192                 int lllca = lca.query(m[son1]+1,m[son2]+1) - 1;
    193                 if(lllca == m[son1] || lllca == m[son2]) 
    194                     cout << Tree[Tree[lllca].fa].name << endl;
    195                 else cout << Tree[ lca.query(m[son1]+1,m[son2]+1) - 1].name<<endl;
    196             }
    197         }
    198     }    
    199 }
  • 相关阅读:
    NS3系列—4———NS3中文教程5:Tweaking NS3
    NS3系列—3———NS3中文:4 概念描述
    NS3系列—2———NS3笔录
    NS3系列—1———NS3中文教程:3下载及编译软件
    How to speed my too-slow ssh login?
    Linux bridge
    使用 GDB 和 KVM 调试 Linux 内核与模块
    How To Set Up A Serial Port Between Two Virtual Machines In VirtualBox
    Linux内核调试环境搭建(基于ubuntu12.04)
    Android
  • 原文地址:https://www.cnblogs.com/helica/p/4792885.html
Copyright © 2011-2022 走看看