标签:
http://poj.org/problem?id=1330
给你一颗有根树,最后输入一对数(a,b),叫你求a和b的公共祖先。
裸的lca,数据也很小,拿来练手不错。
1、tarjan_lca,离线,线性时间复杂度
代码:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<vector> 5 using namespace std; 6 7 const int maxn = 1e4 + 10; 8 9 int n,root; 10 int deg[maxn],vis[maxn],p[maxn]; 11 vector<int> tree[maxn],que[maxn]; 12 13 void init() { 14 memset(deg, 0, sizeof(deg)); 15 for (int i = 0; i <= n; i++) tree[i].clear(); 16 for (int i = 0; i <= n; i++) que[i].clear(); 17 memset(vis, 0, sizeof(vis)); 18 root = -1; 19 } 20 //并查集: 21 int fin(int x) { return p[x] = p[x] == x ? x : fin(p[x]); } 22 void uni(int a, int b) { 23 int pa = fin(a); 24 int pb = fin(b); 25 //不能写成p[pa]=pb,和tarjan算法有关; 26 p[pb] = pa; 27 } 28 29 bool tarjan_LCA(int rt,int& ans) { 30 p[rt] = rt; 31 for (int i = 0; i < tree[rt].size(); i++) { 32 int v = tree[rt][i]; 33 if (tarjan_LCA(v, ans)) return true; 34 //把v并到rt上 35 uni(rt, v); 36 } 37 //涂黑这一点 38 vis[rt] = 1; 39 //处理与rt有关的查询 40 for (int i = 0; i < que[rt].size(); i++) { 41 int qv = que[rt][i]; 42 if (vis[qv]) { 43 ans = fin(qv); 44 return true; 45 } 46 } 47 return false; 48 } 49 50 int main() { 51 int tc; 52 scanf("%d", &tc); 53 while (tc--) { 54 scanf("%d", &n); 55 init(); 56 for (int i = 0; i < n - 1; i++) { 57 int u, v; 58 scanf("%d%d", &u, &v); 59 tree[u].push_back(v); 60 deg[v]++; 61 } 62 int qu, qv; 63 scanf("%d%d", &qu, &qv); 64 que[qu].push_back(qv); 65 que[qv].push_back(qu); 66 for (int i = 1; i <= n; i++) if (deg[i] == 0) { 67 root = i; 68 } 69 int ans; 70 tarjan_LCA(root,ans); 71 printf("%d\n", ans); 72 } 73 return 0; 74 }
2、待续。。。
POJ 1330 Nearest Common Ancestors LCA
标签:
原文地址:http://www.cnblogs.com/fenice/p/5385192.html