hdu 4547 LCA **
题意:在Windows下我们可以通过cmd运行DOS的部分功能,其中CD是一条很有意思的命令,通过CD操作,我们可以改变当前目录。
这里我们简化一下问题,假设只有一个根目录,CD操作也只有两种方式:
1. CD 当前目录名\...\目标目录名 (中间可以包含若干目录,保证目标目录通过绝对路径可达)
2. CD .. (返回当前目录的上级目录)
现在给出当前目录和一个目标目录,请问最少需要几次CD操作才能将当前目录变成目标目录?
链接:点我
先返回到根目录,然后直接前进到目标目录
- #include <iostream>
- #include <string.h>
- #include <algorithm>
- #include <queue>
- #include <map>
- #include <vector>
- #include <math.h>
- #include <string>
- #include <stdio.h>
- #include <math.h>
- using namespace std;
- #define MOD 1000000007
- #define pb(a) push_back(a)
- const int INF=0x3f3f3f3f;
- const double eps=1e-;
- typedef long long ll;
- #define cl(a) memset(a,0,sizeof(a))
- #define ts printf("*****\n");
- const int MAXN=;
- int n,m,ttt;
- int a[MAXN];
- int rmq[*MAXN];//rmq数组,就是欧拉序列对应的深度序列
- struct ST
- {
- int mm[*MAXN];
- int dp[*MAXN][];//最小值对应的下标
- void init(int n)
- {
- mm[] = -;
- for(int i = ;i <= n;i++)
- {
- mm[i] = ((i&(i-)) == )?mm[i-]+:mm[i-];
- dp[i][] = i;
- }
- for(int j = ; j <= mm[n];j++)
- for(int i = ; i + (<<j) - <= n; i++)
- dp[i][j] = rmq[dp[i][j-]] < rmq[dp[i+(<<(j-))][j-]]?dp[i][j-]:dp[i+(<<(j-))][j-];
- }
- int query(int a,int b)//查询[a,b]之间最小值的下标
- {
- if(a > b)swap(a,b);
- int k = mm[b-a+];
- return rmq[dp[a][k]] <= rmq[dp[b-(<<k)+][k]]?dp[a][k]:dp[b-(<<k)+][k];
- }
- };
- //边的结构体定义
- struct Edge
- {
- int to,next;
- };
- Edge edge[MAXN*];
- int tot,head[MAXN];
- int F[MAXN*];//欧拉序列,就是dfs遍历的顺序,长度为2*n-1,下标从1开始
- int P[MAXN];//P[i]表示点i在F中第一次出现的位置
- int cnt;
- ST st;
- void init()
- {
- tot = ;
- memset(head,-,sizeof(head));
- }
- void addedge(int u,int v)//加边,无向边需要加两次
- {
- edge[tot].to = v;
- edge[tot].next = head[u];
- head[u] = tot++;
- }
- void dfs(int u,int pre,int dep)
- {
- F[++cnt] = u;
- rmq[cnt] = dep;
- P[u] = cnt;
- for(int i = head[u];i != -;i = edge[i].next)
- {
- int v = edge[i].to;
- if(v == pre)continue;
- dfs(v,u,dep+);
- F[++cnt] = u;
- rmq[cnt] = dep;
- }
- }
- void LCA_init(int root,int node_num)//查询LCA前的初始化
- {
- cnt = ;
- dfs(root,root,);
- st.init(*node_num-);
- }
- int query_lca(int u,int v)//查询u,v的lca编号
- {
- return F[st.query(P[u],P[v])];
- }
- bool flag[MAXN];
- int Count_num[MAXN];
- int deep[MAXN];
- vector<int>vc[MAXN];
- map<string,int> mp;
- void bfs(int root)
- {
- cl(deep);
- int now,next;
- queue<int> q;
- q.push(root);
- deep[root]=;
- while(!q.empty())
- {
- now=q.front();
- q.pop();
- for(int i=;i<vc[now].size();i++)
- {
- next=vc[now][i];
- if(deep[next]==)
- {
- deep[next]=deep[now]+;
- q.push(next);
- }
- }
- }
- }
- int main()
- {
- int i,j,k;
- #ifndef ONLINE_JUDGE
- freopen("1.in","r",stdin);
- #endif
- scanf("%d",&ttt);
- int ca=;
- while(ttt--)
- {
- scanf("%d%d",&n,&m);
- cl(flag);
- init();
- for(int i=;i<=n;i++)vc[i].clear();
- string u,v;
- mp.clear();
- int tot=;
- char s1[],s2[];
- for(i=;i<n-;i++)
- {
- cin>>u>>v;
- if(mp[u]==) mp[u]=++tot;
- if(mp[v]==) mp[v]=++tot;
- int a1=mp[u];
- int a2=mp[v];
- vc[a2].pb(a1);
- addedge(a2,a1);
- addedge(a1,a2);
- flag[a1]=;
- }
- int root;
- for(int i=;i<=n;i++)
- if(!flag[i])
- {
- root=i;
- break;
- }
- LCA_init(root,n);
- bfs(root);
- for(i=;i<m;i++)
- {
- cin>>u>>v;
- int a1=mp[u];
- int a2=mp[v];
- int temp=query_lca(a1,a2);
- int ans=deep[a1]-deep[temp];
- if(temp!=a2) ans++;
- printf("%d\n",ans);
- }
- }
- }
hdu 4547 LCA **的更多相关文章
- hdu 4547(LCA)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4547 思路:这题的本质还是LCA问题,但是需要注意的地方有: 1.如果Q中u,v的lca为u,那么只需 ...
- 【HDU 4547 CD操作】LCA问题 Tarjan算法
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4547 题意:模拟DOS下的cd命令,给出n个节点的目录树以及m次查询,每个查询包含一个当前目录cur和 ...
- HDU 4547 CD操作 (LCA最近公共祖先Tarjan模版)
CD操作 倍增法 https://i.cnblogs.com/EditPosts.aspx?postid=8605845 Time Limit : 10000/5000ms (Java/Other) ...
- lca讲解 && 例题 HDU - 4547
一. 最普通的找树中两个点x,y最近公共祖先: 在进行lca之前我们要先对这一颗树中的每一个点进行一个编号,像下图一样.这个编号就是tarjan算法中的dfn[]数组 这样的话我们可以在跑tarjan ...
- HDU 3078 (LCA+树链第K大)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3078 题目大意:定点修改.查询树中任意一条树链上,第K大值. 解题思路: 先用离线Tarjan把每个 ...
- HDU 2586 (LCA模板题)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2586 题目大意:在一个无向树上,求一条链权和. 解题思路: 0 | 1 / \ 2 3 ...
- [hdu 2586]lca模板题(在线+离线两种版本)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2586 在线版本: 在线方法的思路很简单,就是倍增.一遍dfs得到每个节点的父亲,以及每个点的深度.然后 ...
- hdu 2874(LCA)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2874 思路:近乎纯裸的LCA,只是题目给出的是森林,就要判断是否都在同一颗树上,这里我们只需判断两个子 ...
- HDU 2586 ( LCA/tarjan算法模板)
链接:http://acm.hdu.edu.cn/showproblem.php?pid=2586 题意:n个村庄构成一棵无根树,q次询问,求任意两个村庄之间的最短距离 思路:求出两个村庄的LCA,d ...
随机推荐
- ubuntu网络连接:Ifupdown(eth0)的连接不能修改或删除
今天其实遇到了三个问题,一个是ubuntu系统上的网络图标不见了,把网络图标弄出来以后有无法联网,联网成功却变成Ifupdown(eth0)的连接且不能修改或删除. 这里我只记录最后一个问题,前两个问 ...
- Next Permutation & Previous Permutation
Next Permutation Given a list of integers, which denote a permutation. Find the next permutation in ...
- Sublime Text 3 注册码失效(被移除)解决方法
最近Sublime Text 3 增加了注册码验证功能,如果你使用共享版本的注册码,可能会提示注册码失效,但是却可以正常激活. 只需要把下面的字段加入到你的hosts文件即可: 127.0.0.1 l ...
- 从一份配置清单详解 Nginx 服务器配置
概述 在前面< Nginx 服务器开箱体验> 一文中我们从开箱到体验,感受了一下 Nginx 服务器的魅力.Nginx 是轻量级的高性能 Web 服务器,提供了诸如 HTTP 代理和反 ...
- IntelliJ IDEA 建空包合并问题。
举例:我想在一个包下,创建2个空子包,这个时候,却无法再IDE里完成. 老是这样子,如果选中dff.sfsdf再右键 创建包的话,结局是再sfsdf下 又创建一个文件夹. 如果右键创建类的话,实际上在 ...
- Codeforces 552C Vanya and Scales(进制转换+思维)
题目链接:http://codeforces.com/problemset/problem/552/C 题目大意:有101个砝码重量为w^0,w^1,....,w^100和一个重量为m的物体,问能否在 ...
- 【LOJ】 #2305. 「NOI2017」游戏
题解 枚举x所在的地图的颜色,然后2-SAT建边 如果v所在的地图刚好是不能选的,那么u这边只能选另一种颜色 否则就是u的颜色到v的颜色 v的另一种颜色到u的另一种颜色 代码 #include < ...
- 【POJ】1286.Necklace of Beads
题解 群论,我们只要找出所有的置换群的所有循环节 具体可参照算法艺术与信息学竞赛 旋转的置换有n个,每一个的循环节个数是gcd(N,i),i的范围是0到N - 1 翻转,对于奇数来说固定一个点,然后剩 ...
- USACO 4.3 Letter Game (字典树)
Letter GameIOI 1995 Figure 1: Each of the 26 lowercase letters and its value Letter games are popula ...
- Failed to load JavaHL Library. SVN
以前使用的电脑是32位的,安装的svn可以正常使用,但是现在的电脑室64位的,安装好svn后,把项目提交到svn的过程中,总是弹出来一个错误的对话框: Failed to load JavaHL Li ...