Poj--1470(LCA,离线tarjan / 在线倍增)

2014-10-26 12:13:10

思路:lca启蒙题,比较裸的一题,水过吧。有离线Tarjan和在线倍增两种做法。

离线Tarjan:

 

  1 /*************************************************************************
  2     > File Name: 1470.cpp
  3     > Author: Nature
  4     > Mail: 564374850@qq.com 
  5     > Created Time: Sat 25 Oct 2014 06:50:04 PM CST
  6 ************************************************************************/
  7 
  8 #include <cstdio>
  9 #include <cstring>
 10 #include <cstdlib>
 11 #include <cmath>
 12 #include <vector>
 13 #include <map>
 14 #include <set>
 15 #include <stack>
 16 #include <queue>
 17 #include <iostream>
 18 #include <algorithm>
 19 using namespace std;
 20 #define lp (p << 1)
 21 #define rp (p << 1|1)
 22 #define getmid(l,r) (l + (r - l) / 2)
 23 #define MP(a,b) make_pair(a,b)
 24 typedef long long ll;
 25 const int INF = 1 << 30;
 26 const int maxn = 1000;
 27 
 28 int n,m;
 29 int first[maxn],next[maxn * maxn],ver[maxn * maxn],ecnt;
 30 int fa[maxn];
 31 int que[maxn][maxn];
 32 int vis[maxn];
 33 int cnt[maxn],f[maxn];
 34 
 35 int Find(int x){
 36     return fa[x] == x ? x : fa[x] = Find(fa[x]); //并查集find,路径压缩
 37 }
 38 
 39 void Union(int u,int v){
 40     int x = Find(u);
 41     int y = Find(v);
 42     if(x != y)
 43         fa[y] = x; //后者以前者为祖先
 44 }
 45 
 46 void Add_edge(int u,int v){
 47     next[++ecnt] = first[u];
 48     ver[ecnt] = v;
 49     first[u] = ecnt;
 50 }
 51 
 52 void Init(){
 53     memset(f,0,sizeof(f));
 54     memset(cnt,0,sizeof(cnt));
 55     memset(que,0,sizeof(que));
 56     memset(vis,0,sizeof(vis));
 57     memset(first,-1,sizeof(first));
 58     ecnt = 0;
 59 }
 60 
 61 void Tarjan(int p){
 62     fa[p] = p; //先把遍历到的点p自己加入一个集合
 63     for(int i = first[p]; i != -1; i = next[i]){
 64         int v = ver[i];
 65         Tarjan(v); //遍历子节点
 66         Union(p,v); //因为p是其所有子节点的祖先,所以并进集合,并以p为祖先
 67     }
 68     vis[p] = 1; //表示以p为根的整棵子树已经访问完毕
 69     for(int i = 1; i <= n; ++i) if(que[p][i] && vis[i]){
 70         cnt[Find(i)] += que[p][i];
 71         //询问的是(p,i),如果i已经访问过,那么说明遍历到lca(p,i)时
 72         //是先遍历到包含i的子树,再遍历包含p的子树。那么i当前的最祖先节点必然
 73         //是p和i的最近公共祖先(因为i的最祖先节点是不断更新的,一旦能发现p点,
 74         //那么当前最祖先节点是最近的。)
 75 
 76         //que[p][i] = que[i][p] = 0;
 77         //上句话其实没有必要,因为一对关系只会求一次。每次关系会处理到
 78         //两次,必定有一次是只有一个点遍历过,另一个点没有遍历过
 79     }
 80 }
 81 
 82 int main(){
 83     int a,b,k;
 84     while(scanf("%d",&n) != EOF){
 85         Init();
 86         for(int i = 1; i <= n; ++i){
 87             scanf("%d:(%d)",&a,&k);
 88             while(k--){
 89                 scanf("%d",&b);
 90                 Add_edge(a,b); //单条有向边
 91                 f[b] = 1; //用于区别出根节点与其他节点
 92             }
 93         }
 94         char c;
 95         scanf("%d",&m);
 96         for(int i = 1; i <= m; ++i){
 97             c = getchar();
 98             while(c != '(') c = getchar();
 99             scanf("%d%d",&a,&b);
100             c = getchar();
101             while(c != ')') c = getchar();
102             que[a][b]++; //对称地记录询问
103             que[b][a]++;
104         }
105         for(int i = 1; i <= n; ++i)
106             if(!f[i]){
107                 Tarjan(i); //i就为整棵树的根节点
108                 break;
109             }
110         for(int i = 1; i <= n; ++i) if(cnt[i]){
111             printf("%d:%d\n",i,cnt[i]);
112         }
113     }
114     return 0;
115 }
View Code

 

在线倍增(后学):

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <cstdlib>
  4 #include <cmath>
  5 #include <vector>
  6 #include <map>
  7 #include <set>
  8 #include <stack>
  9 #include <queue>
 10 #include <string>
 11 #include <iostream>
 12 #include <algorithm>
 13 using namespace std;
 14 
 15 #define MEM(a,b) memset(a,b,sizeof(a))
 16 #define REP(i,n) for(int i=1;i<=(n);++i)
 17 #define REV(i,n) for(int i=(n);i>=1;--i)
 18 #define FOR(i,a,b) for(int i=(a);i<=(b);++i)
 19 #define RFOR(i,a,b) for(int i=(a);i>=(b);--i)
 20 #define getmid(l,r) ((l) + ((r) - (l)) / 2)
 21 #define MP(a,b) make_pair(a,b)
 22 
 23 typedef long long ll;
 24 typedef pair<int,int> pii;
 25 const int INF = (1 << 30) - 1;
 26 const int MAXN = 1010;
 27 const int MAX_LOG = 10;
 28 
 29 int n,m,first[MAXN],ecnt,f[MAXN],root;
 30 int fa[11][MAXN],dep[MAXN];
 31 int lca[MAXN];
 32 
 33 struct edge{
 34     int v,next;
 35 }e[MAXN * MAXN];
 36 
 37 void Add_edge(int u,int v){
 38     e[++ecnt].next = first[u];
 39     e[ecnt].v = v;
 40     first[u] = ecnt;
 41 }
 42 
 43 void Dfs(int p,int pre,int d){
 44     fa[0][p] = pre;
 45     dep[p] = d;
 46     for(int i = first[p]; ~i; i = e[i].next){
 47         int v = e[i].v;
 48         if(v == pre) continue;
 49         Dfs(v,p,d + 1);
 50     }
 51 }
 52 
 53 void Init(){
 54     Dfs(root,-1,0);
 55     for(int k = 0; k + 1 < MAX_LOG; ++k){
 56         for(int i = 1; i <= n; ++i){
 57             if(fa[k][i] < 0) fa[k + 1][i] = -1;
 58             else fa[k + 1][i] = fa[k][fa[k][i]];
 59         }
 60     }
 61 }
 62 
 63 void Lca(int u,int v){
 64     if(dep[u] > dep[v]) swap(u,v);
 65     for(int k = 0; k < MAX_LOG; ++k){
 66         if((dep[v] - dep[u]) & (1 << k))
 67             v = fa[k][v];
 68     }
 69     if(u == v){
 70         lca[u]++;
 71         return;
 72     }
 73     for(int k = MAX_LOG - 1; k >= 0; --k){
 74         if(fa[k][u] != fa[k][v]){
 75             u = fa[k][u];
 76             v = fa[k][v];
 77         }
 78     }
 79     lca[fa[0][u]]++;
 80 }
 81 
 82 int main(){
 83     char c;
 84     int a,b,k;
 85     while(scanf("%d",&n) != EOF){
 86         MEM(first,-1);
 87         MEM(f,0);
 88         MEM(lca,0);
 89         ecnt = 0;
 90         REP(i,n){
 91             scanf("%d:(%d)",&a,&k);
 92             while(k--){
 93                 scanf("%d",&b);
 94                 Add_edge(a,b);
 95                 f[b] = 1;
 96             }
 97         }
 98         REP(i,n) if(!f[i]){
 99             root = i;
100             break;
101         }
102         Init();
103         scanf("%d",&m);
104         REP(i,m){
105             c = getchar();
106             while(c != '(') c = getchar();
107             scanf("%d%d",&a,&b);
108             while(c != ')') c = getchar();
109             Lca(a,b);
110         }
111         REP(i,n) if(lca[i])
112             printf("%d:%d\n",i,lca[i]);
113     }
114     return 0;
115 }

 

转载于:https://www.cnblogs.com/naturepengchen/articles/4051830.html

论文复现5:UMI Universal Manipulation Interface UMI 采用手持式夹具,加上精心的界面设计,可实现便携式、低成本和信息丰富的数据收集,以进行具有挑战性的双手和动态操作演示。配备这些功能后,UMI 框架解锁了新的机器人操作功能,只需更改每个任务的训练数据,即可实现零样本可推广的动态、双手、精确和长视野行为。我们通过全面的现实世界实验展示了 UMI 的多功能性和有效性,其中通过 UMI Zeroshot 学习的策略在对不同的人类演示进行训练时可以推广到新的环境和对象。项目主页:https://umi-gripper.github.io/ 阅读详情

相关推荐

python机器人编程——用pytorch实现六轴机械臂的正向和逆向数值解算,及python算法解析

前面对六轴(或多轴)机械臂进行了一些研究,特别是利用几何进行简化,实现逆解,来完成比较简单的搬用任务。然而,如果需要比较精确的操作任务,可能需要更加复杂的机械臂解算。其中比较复杂的是数值解算,这种解算往往涉及到比较复杂的机器人运动等原理知识,比较难以上手。但是,python的生态挺全面,已经有很多牛人实现了数值解法,但是去看他们的代码,还是觉得费劲。此外,随着深度神经网络的兴起,很多是用建立深度学习神经网络,去利用机械臂输入输出的大数据,训练机械臂的控制模型,这个上手也比较慢。

JAMES费的空间 5794

poj3417 Network(tarjan)(lca)(并查集)

题意 给出一个图,然后执行Q个操作,每次往里面添加一条边,并输出桥(割边)的数量。 题解 tarjan+lca+并查集(路径压缩) 用tarjan很容易求出原图中所有的桥。 考虑加边的情况。 如果加在一个e-dcc中,不必理会。 如果不是,那么从x到y一路上的桥都将消失。处理这个问题,只需要把(x,y)路径上所有边都枚举一下,如果bridge[i]==true,那么ans--。因为这段路上的...

A_Bright_CH的博客 407

用5毫欧采样电阻实现高精度电流检测?数字可调电源控制板的硬件设计陷阱

本文深入探讨了在数字可调电源控制板设计中,如何利用5毫欧采样电阻实现高精度电流检测。从微小信号放大电路设计、采样电阻布局与热管理,到电源切换与电池管理电路优化,提供了全面的硬件设计解决方案和实用技巧,帮助工程师规避常见设计陷阱,提升系统性能。

wdx0123456的博客 1030

最近公共祖先(LCA)详解

LCA问题(Least Common Ancestors,最近公共祖先问题),是指给定一棵有根树T,给出若干个查询LCA(u, v)(通常查询数量较大),每次求树T中两个顶点u和v的最近公共祖先,即找一个节点,同时是u和v的祖先,并且深度尽可能大(尽可能远离树根)。 LCA问题有很多解法:线段树、Tarjan算法、跳表、RMQ与LCA互相转化等。本文主要讲解Tarjan算法的原理及详细实现。

白学病患者的专栏 3789

北京联通IPTV组播实战:OpenWRT软路由配置全解析

本文详细解析了在北京联通IPTV环境下,利用OpenWRT软路由和udpxy工具实现组播转单播的实战配置。内容涵盖网络接口设置、防火墙规则、udpxy安装配置、直播源M3U文件处理以及全平台播放指南,帮助用户无需机顶盒即可在家庭局域网内任何设备上流畅观看电视直播。

weixin_29313547的博客 1410

手机安装Kali Linux

在数字化时代,信息安全和隐私保护显得尤为重要。,作为一款专业的和工具,因其强大的功能和丰富的资源库而受到广大安全研究者和爱好者的青睐。然而,我们通常只能在传统的电脑设备上安装和使用Kali Linux。那么,有没有可能将也变成一款随身携带的Kali Linux设备呢?答案是肯定的。本文将介绍如何在手机上安装Kali Linux,使你的手机变成一款强大的移动安全工具。,我们需要明确一点,手机安装Kali Linux并非简单的操作,需要对手机进行一定的改造和配置。

2301_80124151的博客 6966

POJ 1470(LCA)

Closest Common Ancestors   Description   有一颗树,求给定两节点的公共祖先,最后输出每个节点当做祖先的次数。 Input   输入文件包含多组测试数据。   对于每组测试数据的第一行为一个整数n(n&lt;=900),表示结点个数   接下来n行,每行输入形式为k:(t)k1 k2…kt;第一个数字...

niuniu0205的博客 774

从工创赛实战到开源:一个高鲁棒性智能物流视觉系统的构建与优化

本文分享了从工创赛实战中构建高鲁棒性智能物流视觉系统的完整经验。针对赛场复杂光线环境,详细阐述了摄像头选型、基于CLAHE和形态学梯度的抗干扰色环识别算法、卡尔曼滤波状态估计以及多线程串口通讯与任务调度等核心优化策略,旨在打造一个稳定可靠的视觉系统,并已将相关代码开源。

weixin_29046035的博客 320

POJ1470 (Closest Common Ancestors)

Write a program that takes as input a rooted tree and a list of pairs of vertices. For each pair (u,v) the program determines the closest common ancestor of u and v in the tree. The closest common ...

qq_42445959的博客 343

PyTorch深度学习实战(36)——Pix2Pix详解与实现

Pix2Pix 是基于生成对抗网络的图像转换框架,能够将输入图像转换为与之对应的输出图像,能够广泛用于图像到图像转换的任务,如风格转换、图像修复、语义标签到图像的转换等。Pix2Pix 的核心思想是通过对抗训练将输入图像和目标输出图像进行配对,使生成网络可以学习到输入图像到输出图像的映射关系。在本节中,将学习使用 Pix2Pix 根据给定轮廓生成图像。

盼小辉丶的博客 1万+

无迹卡尔曼滤波 (UKF, Unscented Kalman Filter) 算法详解及案例分析

无迹卡尔曼滤波是一种用于估计非线性系统状态的递归算法。其目标是通过结合系统模型和观测数据,估计系统的最优状态。

闲人编程的博客 2629

poj-1470

//3452K 735MS C++ #include #include const int MAX = 910; struct TreeNode { int NextBroId; int parentId; }; typedef struct TreeNode TreeNode; int LCACounter[MAX]; int querys[MAX][MAX];

fyfcauc的专栏 659

从零开始学 PyTorch 7天路线图(完整可运行代码版)

本文提供了5天PyTorch入门教程的完整代码,涵盖从基础到实战的核心内容。Day1测试环境并介绍张量基础;Day2讲解常用张量操作;Day3演示自动求导机制;Day4实现完整线性回归模型;Day5构建MNIST手写数字识别全连接网络。所有代码可直接运行,包含GPU检测、梯度计算、模型训练和可视化等关键环节,帮助新手快速掌握PyTorch核心概念和典型应用场景。

IT老农民的博客 314

LCA(最近公共祖先)——Tarjan

什么是最近公共祖先? 在一棵没有环的树上,每个节点肯定有其父亲节点和祖先节点,而最近公共祖先,就是两个节点在这棵树上深度最大的公共的祖先节点。 换句话说,就是两个点在这棵树上距离最近的公共祖先节点。 所以LCA主要是用来处理当两个点仅有唯一一条确定的最短路径时的路径。 常用来求LCA的算法有:Tarjan/DFS(离线),ST/倍增(在线)。 1,Tarjan tarjan...

weixin_34148456的博客 264

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

(算法)Tarjan离线算法解决LCA问题 (附POJ 1470 Closest Common Ancestors 代码)

对于最近公共祖先问题,我们先来看这样一个性质,当两个节点(u,v)的最近公共祖先是x时,那么我们可以确定的说,当进行后序遍历的时候,必然先访问完x的所有子树,然后才会返回到x所在的节点。这个性质就是我们使用Tarjan算法解决最近公共祖先问题的核心思想。      同时我们会想这

Bright 7911

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

LCA

ACM模版DFS + ST在线算法参考题目链接: POJ 1330 Nearest Common Ancestorsconst int MAXN = 10010; int rmq[2 * MAXN]; // rmq数组,就是欧拉序列对应的深度序列struct ST { int mm[2*MAXN]; int dp[2*MAXN][20]; // 最小值

逐梦者 1724

POJ 1470 Closest Common Ancestors (LCA)

Description Write a program that takes as input a rooted tree and a list of pairs of vertices. For each pair (u,v) the program determines the closest common ancestor of u and v in the tree. The close

小坏蛋_千千 683

LCA转RMQ

最近一直在被lrj的紫书的最后一章虐,前几天写LCT被卡常数卡成狗,现在来玩玩LCA。 以前用的都是Tarjan求LCA,只能处理离线问题(倍增老写错所以就懒得用了),今天学了下欧拉序列,随手下了个LCA,然后又写挂了。。。。。。写错了一个变量名这事不能怪我TAT。 其实利用欧拉序列求LCA的思想还是很简单的。 我们令pos(k)为节点k在欧拉序列中第一次出现的序号,再得到一个深度序列B,B

月下沙茶树 420

Closest Common Ancestors【POJ1470】——LCA

Time Limit: 2000MS Memory Limit: 10000KDescriptionWrite a program that takes as input a rooted tree and a list of pairs of vertices. For each pair (u,v) the program determines the closest common a

绝尘 1021

HDU2586 How far away? LCA

解决LCA问题主要有在线算法和离线算法。在线算法(问一次答一次):DFS+ST(RMQ)/倍增;离线算法(全部问完了再回答):Tarjan+并查集。先附上讲解博客Orz:(模板是上海大学kuangbin的模板) 在线算法:https://blog.youkuaiyun.com/u013076044/article/details/41870751 https://blo...

A confused programmer 269

POJ-1470-Closest Common Ancestors 解题报告

LCA简单基础入门题。赤裸裸的q

JZQT_T的博客 870

lca

//目前会三个版本 //1.倍增法。看挑战。 //2.rmq.看挑战 //3.离线 tarjan看http://www.cnblogs.com/JVxie/p/4854719.html //离线的基本原理是依据dfs的括号性的(看算法导论找dfs括号性) //在已知各个询问的时候我们阔以用并查集来辅助。。首先init() 另father[i]=i;然后开始dfs() //这里还需要一个visit

guoshiyuan484的博客 527

POJ 1470(LCA离线算法)

/* LCA离线算法: void(int root){ 判断当前节点root是不是要查询集合组中一个点,如果是,那么查看组另一个点 ,如查被标记了,那么找这个点的根节点;就是他们两个的最近的公共祖先; 标记root这个点; LCA(遍历 root下的所有结点) } */ #include &lt;iostream&gt; #include &lt;fstr...

julicliy的博客 557

poj 1470(简单LCA 倍增法)

题意:给你一个树,有若干个询问,然后让你统计每个结点在询问中做了几次LCA。按照结点顺序输出。 思路:这也是简单的LCA题目,我用的是倍增法。每次查询在相应结点标记上++,最后输出即可。这道题的输入处理比较烦,而且第一个输入的结点并不是根节点。这要注意一下 代码如下: 1 #include <iostream> 2 #include <cstdio> ...

weixin_34087301的博客 230

POJ1470 倍增法在线求LCA

其实本质是就是一种二分。 首先我们先对这个树DFS一遍,记录每个节点的深度(depth),并且记录他的第2^j个祖先。 当我们找u和v的LCA时,首先把他们的深度变成一样的,然后如果pre[u][k] == pre[v][k],那么当前是公共祖先,但不一定是最近的,所以k--; 如果不符合就u = pre[u][k] v = pre[v][k],接着找。 #include #includ

cugb1004101218的专栏 1379

LCA 最近公共祖先 tarjan离线 总结 结合3个例题

在网上找了一些对tarjan算法解释较好的文章 并加入了自己的理解   LCA(Least Common Ancestor),顾名思义,是指在一棵树中,距离两个点最近的两者的公共节点。也就是说,在两个点通往根的道路上,肯定会有公共的节点,我们就是要求找到公共的节点中,深度尽量深的点。还可以表示成另一种说法,就是如果把树看成是一个图,这找到这两个点中的最短距离。       LCA

hnust_xiehonghao的专栏 1万+

poj1470 LCA倍增法

倍增法模板题 #include<iostream> #include<cstring> #include<cstdio> #include<queue> using namespace std; #define maxn 1000 #define DEG 20 struct Edge{ int to,next; }ed...

weixin_30788731的博客 158
上一篇: CF #200 div2 虚拟赛
下一篇: Poj--1330(LCA,tarjan)
dingdi3021
博客等级 码龄11年 1粉丝 230原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值