hdu 4547 (LCA 倍增法)
2014-01-22 15:46
106 查看
中文题就不解释了。
简单LCA,就是求第一个点到LCA的距离,在判断第二个点是不是LCA,不是答案再加一就可。至于求距离的话直接利用倍增法的parent数组拆成二进制复杂度为logn。
代码如下:
View Code
简单LCA,就是求第一个点到LCA的距离,在判断第二个点是不是LCA,不是答案再加一就可。至于求距离的话直接利用倍增法的parent数组拆成二进制复杂度为logn。
代码如下:
#include <iostream> #include <cstdio> #include <cstdlib> #include <cmath> #include <cstring> #include <algorithm> #include <queue> #include <stack> #include <vector> #include <set> #include <map> #define MP(a, b) make_pair(a, b) #define PB(a) push_back(a) using namespace std; typedef long long ll; typedef pair<int ,int> pii; typedef pair<unsigned int, unsigned int> puu; typedef pair<int ,double> pid; typedef pair<ll, int> pli; const int INF = 0x3f3f3f3f; const double eps = 1e-6; const int LEN = 100010; const int LOG_LEN = 22; vector<int> Map[LEN]; map<string, int> mp; int ind[LEN], n ,m, root, depth[LEN], parent[LOG_LEN][LEN]; void dfs(int v, int p, int d){ parent[0][v] = p; depth[v] = d; for(int i=0; i<Map[v].size(); i++){ if(Map[v][i]!=p) dfs(Map[v][i], v, d+1); } } void init(int n) { dfs(root, -1, 0); for(int k=0; k+1<LOG_LEN; k++){ for(int i=0; i<n; i++){ if(parent[k][i]<0) parent[k+1][i] = -1; else parent[k+1][i] = parent[k][parent[k][i]]; } } } int lca(int u, int v) { int ret = 0; if(depth[u]>depth[v])swap(u, v); for(int k=0; k<LOG_LEN; k++){ if((depth[v]-depth[u]) >> k & 1) v = parent[k][v]; } if(u==v) return u; for(int k=LOG_LEN-1; k>=0; k--){ if(parent[k][u]!=parent[k][v]){ u = parent[k][u]; v = parent[k][v]; } } return parent[0][v]; } int solve(int v, int p){ int ret = 0; for(int i=LOG_LEN-1; i>=0; i--) if(parent[i][v]!=-1 && depth[parent[i][v]]>=depth[p]){ v = parent[i][v]; ret+=(1<<i); } return ret; } int main() { // freopen("in.txt", "r", stdin); int T, a, b; char va[110], vb[110]; scanf("%d", &T); while(T--){ for(int i=0; i<LEN; i++)Map[i].clear(); mp.clear(); memset(ind, 0, sizeof ind); scanf("%d%d", &n, &m); int vcnt = 0; for(int i=0; i<n-1; i++){ scanf("%s%s", va, vb); if(!mp.count(va)) mp[va] = vcnt++; if(!mp.count(vb)) mp[vb] = vcnt++; ind[mp[va]] ++; Map[mp[va]].PB(mp[vb]); Map[mp[vb]].PB(mp[va]); } for(int i=0; i<n; i++)if(!ind[i]){root = i;break;} init(n); for(int i=0; i<m; i++){ scanf("%s%s", va, vb); int lv = lca(mp[va], mp[vb]); printf("%d\n", solve(mp[va], lv)+(lv==mp[vb]?0:1)); } } return 0; }
View Code
相关文章推荐
- hdu 4547(LCA+Tarjan)
- hdu 4547(tarjan LCA)
- hdu 4547 LCA **
- hdu 4547(LCA)
- hdu 4547 Tarjan LCA 离线算法
- hdu 2586 How far away ? 最近公共祖先lca 在线算法(倍增法)/离线算法(Tarjan算法)
- hdu 4547(LCA)
- HDU-4547 CD操作 LCA
- hdu 4547 CD操作(金山居 LCA算法)
- HDU 4547 lca
- HDU-4547-离线LCA
- HDU_4547_CD操作(LCA+tarjan)
- HDU 2586 How far away LCA 倍增法
- HDU 4547 CD操作(LCA)
- Hdu 4547 CD操作 LCA问题
- hdu_4547_CD操作(在线LCA)
- HDU 4547 CD操作 LCA
- HDU - 4547 - CD操作(LCA)
- Hdu 4547 CD操作 LCA问题
- hdu_4547_CD操作(在线LCA)