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\n",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\n",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\n",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 }