简单的LCA

  这么久了才做LCA的题,以前是感觉很难不敢去尝试,现在学习了一番之后发现算法本身并不难。。。。

 

  学习时看了这篇博文:https://www.cnblogs.com/JVxie/p/4854719.html, 我觉得实现的过程最重要,就把博文中Tarjan算法实现的方法以及伪代码贴到下面:

 

         Tarjan算法的基本思路:

      1.任选一个点为根节点,从根节点开始。

      2.遍历该点u所有子节点v,并标记这些子节点v已被访问过。

      3.若是v还有子节点,返回2,否则下一步。

      4.合并v到u上。

      5.寻找与当前点u有询问关系的点v。

      6.若是v已经被访问过了,则可以确认u和v的最近公共祖先为v被合并到的父亲节点a。

    遍历的话需要用到dfs来遍历,至于合并,最优化的方式就是利用并查集来合并两个节点。

    下面上伪代码:

Tarjan(u)//marge和find为并查集合并函数和查找函数
{
    for each(u,v)    //访问所有u子节点v
    {
        Tarjan(v);        //继续往下遍历
        marge(u,v);    //合并v到u上
        标记v被访问过;
    }
    for each(u,e)    //访问所有和u有询问关系的e
    {
        如果e被访问过;
        u,e的最近公共祖先为find(e);
    }
}

 

 

    算法的运用以及实现过程的举例,博文中讲的很详细,我想补充一下我对Tarjan算法的理解,

  当程序在dfs过程中遍历到某个节点 N 时, 以 N 节点为根节点搜索它的子节点,在它的某一子节点或某一子树都遍历过后,遍历过的点的父节点都会变成节点 N。那么假设N的子树中 i 节点被遍历了,其父节点变成N ; 遍历到其他子节点 j 时, 若恰好存在询问 i , j ,且 i , j 都在以 N 为根的树内,那么就可以直接得到 i, j 的LCA为 N 节点。那么在一次dfs过程中就都得到了所有询问的LCA

 

以下是两道例题的AC代码:

 

CODEVS 2370 小机房的树

 

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<vector> 
 5 using namespace std;
 6 const int MAXN=75005;
 7 struct Edge{
 8     int to;
 9     int cost;
10     int id;
11 };
12 vector<Edge> vec[MAXN];
13 vector<Edge> Q[MAXN];
14 bool vis[MAXN];
15 int p[MAXN], res[MAXN];
16 long long d[MAXN], resd[MAXN];
17 void add_edge(int u, int v, int c){
18     vec[u].push_back((Edge){v, c, -1});
19     vec[v].push_back((Edge){u, c, -1});
20 }
21 void add_query(int a, int b, int id){
22     Q[a].push_back((Edge){b, 0, id});
23     Q[b].push_back((Edge){a, 0, id});
24 }
25 int find(int x){
26     return (p[x]==x)?x:(p[x]=find(p[x]));
27 }
28 void Union(int x, int y)
29 {
30     x=find(x);
31     y=find(y);
32     if(x==y) return;
33     else p[x]=y;
34 }
35 void tarjan(int now, int fa)
36 {
37     for(int i=0;i<vec[now].size();i++){
38         Edge e=vec[now][i];
39         if(!vis[e.to]&&e.to!=fa){
40             /**/
41             d[e.to]=d[now]+e.cost; 
42             /**/ 
43             tarjan(e.to, now);
44             Union(e.to, now);//注意now 和 e.to 的顺序
45             
46         } 
47     }
48     for(int i=0;i<Q[now].size();i++){
49         Edge e=Q[now][i];
50         if(vis[e.to]){
51             res[e.id]=find(e.to);
52             resd[e.id]=d[e.to]+d[now]-2*d[res[e.id]];
53         }
54     }
55     vis[now]=1;
56 }
57 int main()
58 {
59     int n,m,a,b,c;
60     while(~scanf("%d", &n))
61     {
62         for(int i=0;i<=n;i++) p[i]=i;
63         for(int i=0;i<n-1;i++){
64             scanf("%d %d %d", &a, &b, &c);
65             add_edge(a, b, c);
66         }
67         scanf("%d", &m);
68         for(int i=0;i<m;i++){
69             scanf("%d %d", &a, &b);
70             add_query(a, b, i);
71         }
72         
73         memset(vis, 0, sizeof(vis));
74         memset(d, 0, sizeof(d));
75         tarjan(0, -1);
76         for(int i=0;i<m;i++){
77             printf("%lld\n", resd[i]);
78         }
79     }
80 } 
81 /*
82 9
83 1 2 0
84 1 3 0
85 2 4 0
86 2 5 0
87 3 6 0
88 5 7 0
89 5 8 0
90 7 9 0
91 4
92 9 8
93 4 6
94 7 5
95 5 3
96 */
View Code

 

CODEVS 1036 商务旅行

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<vector> 
 5 using namespace std;
 6 const int MAXN=75005;
 7 struct Edge{
 8     int to;
 9     int cost;
10     int id;
11 };
12 vector<Edge> vec[MAXN];
13 vector<Edge> Q[MAXN];
14 bool vis[MAXN];
15 int p[MAXN], res[MAXN];
16 long long d[MAXN], resd[MAXN];
17 void add_edge(int u, int v, int c){
18     vec[u].push_back((Edge){v, c, -1});
19     vec[v].push_back((Edge){u, c, -1});
20 }
21 void add_query(int a, int b, int id){
22     Q[a].push_back((Edge){b, 0, id});
23     Q[b].push_back((Edge){a, 0, id});
24 }
25 int find(int x){
26     return (p[x]==x)?x:(p[x]=find(p[x]));
27 }
28 void Union(int x, int y)
29 {
30     x=find(x);
31     y=find(y);
32     if(x==y) return;
33     else p[x]=y;
34 }
35 void tarjan(int now, int fa)
36 {
37     for(int i=0;i<vec[now].size();i++){
38         Edge e=vec[now][i];
39         if(!vis[e.to]&&e.to!=fa){
40             /**/
41             d[e.to]=d[now]+e.cost; 
42             /**/ 
43             tarjan(e.to, now);
44             Union(e.to, now);//注意now 和 e.to 的顺序
45             
46         } 
47     }
48     for(int i=0;i<Q[now].size();i++){
49         Edge e=Q[now][i];
50         if(vis[e.to]){
51             res[e.id]=find(e.to);
52             resd[e.id]=d[e.to]+d[now]-2*d[res[e.id]];
53         }
54     }
55     vis[now]=1;
56 }
57 int main()
58 {
59     int n,m,a,b,c;
60     while(~scanf("%d", &n))
61     {
62         for(int i=0;i<=n;i++) p[i]=i;
63         for(int i=0;i<n-1;i++){
64             scanf("%d %d", &a, &b);
65             add_edge(a, b, 1);
66         }
67         scanf("%d", &m);
68         scanf("%d", &a);
69         for(int i=1;i<m;i++){
70             scanf("%d", &b);
71             add_query(a, b, i);
72             a=b;
73         }
74         
75         memset(vis, 0, sizeof(vis));
76         memset(d, 0, sizeof(d));
77         tarjan(1, -1);
78         long long ans=0;
79         for(int i=1;i<m;i++){
80             ans+=resd[i];
81         }
82         printf("%lld\n", ans);
83     }
84 } 
View Code

 

转载于:https://www.cnblogs.com/MasterSpark/p/7848054.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
VR(Virtual Reality)即虚拟现实,是一种可以创建和体验虚拟世界的计算机技术。它利用计算机生成一种模拟环境,是一种多源信息融合的、交互式的三维动态视景和实体行为的系统仿真,使用户沉浸到该环境中。VR技术通过模拟人的视觉、听觉、触觉等感觉器官功能,使人能够沉浸在计算机生成的虚拟境界中,并能够通过语言、手势等自然的方式与之进行实时交互,创建了一种适人化的多维信息空间。 VR技术具有以下主要特点: 沉浸感:用户感到作为主角存在于模拟环境中的真实程度。理想的模拟环境应该使用户难以分辨真假,使用户全身心地投入到计算机创建的三维虚拟环境中,该环境中的一切看上去是真的,听上去是真的,动起来是真的,甚至闻起来、尝起来等一切感觉都是真的,如同在现实世界中的感觉一样。 交互性:用户对模拟环境内物体的可操作程度和从环境得到反馈的自然程度(包括实时性)。例如,用户可以用手去直接抓取模拟环境中虚拟的物体,这时手有握着东西的感觉,并可以感觉物体的重量,视野中被抓的物体也能立刻随着手的移动而移动。 构想性:也称想象性,指用户沉浸在多维信息空间中,依靠自己的感知和认知能力获取知识,发挥主观能动性,寻求解答,形成新的概念。此概念不仅是指观念上或语言上的创意,而且可以是指对某些客观存在事物的创造性设想和安排。 VR技术可以应用于各个领域,如游戏、娱乐、教育、医疗、军事、房地产、工业仿真等。随着VR技术的不断发展,它正在改变人们的生活和工作方式,为人们带来全新的体验。
VR(Virtual Reality)即虚拟现实,是一种可以创建和体验虚拟世界的计算机技术。它利用计算机生成一种模拟环境,是一种多源信息融合的、交互式的三维动态视景和实体行为的系统仿真,使用户沉浸到该环境中。VR技术通过模拟人的视觉、听觉、触觉等感觉器官功能,使人能够沉浸在计算机生成的虚拟境界中,并能够通过语言、手势等自然的方式与之进行实时交互,创建了一种适人化的多维信息空间。 VR技术具有以下主要特点: 沉浸感:用户感到作为主角存在于模拟环境中的真实程度。理想的模拟环境应该使用户难以分辨真假,使用户全身心地投入到计算机创建的三维虚拟环境中,该环境中的一切看上去是真的,听上去是真的,动起来是真的,甚至闻起来、尝起来等一切感觉都是真的,如同在现实世界中的感觉一样。 交互性:用户对模拟环境内物体的可操作程度和从环境得到反馈的自然程度(包括实时性)。例如,用户可以用手去直接抓取模拟环境中虚拟的物体,这时手有握着东西的感觉,并可以感觉物体的重量,视野中被抓的物体也能立刻随着手的移动而移动。 构想性:也称想象性,指用户沉浸在多维信息空间中,依靠自己的感知和认知能力获取知识,发挥主观能动性,寻求解答,形成新的概念。此概念不仅是指观念上或语言上的创意,而且可以是指对某些客观存在事物的创造性设想和安排。 VR技术可以应用于各个领域,如游戏、娱乐、教育、医疗、军事、房地产、工业仿真等。随着VR技术的不断发展,它正在改变人们的生活和工作方式,为人们带来全新的体验。
基于GPT-SoVITS的视频剪辑快捷配音工具 GPT, 通常指的是“Generative Pre-trained Transformer”(生成式预训练转换器),是一个在自然语言处理(NLP)领域非常流行的深度学习模型架构。GPT模型由OpenAI公司开发,并在多个NLP任务上取得了显著的性能提升。 GPT模型的核心是一个多层Transformer解码器结构,它通过在海量的文本数据上进行预训练来学习语言的规律。这种预训练方式使得GPT模型能够捕捉到丰富的上下文信息,并生成流畅、自然的文本。 GPT模型的训练过程可以分为两个阶段: 预训练阶段:在这个阶段,模型会接触到大量的文本数据,并通过无监督学习的方式学习语言的结构和规律。具体来说,模型会尝试预测文本序列中的下一个词或短语,从而学习到语言的语法、语义和上下文信息。 微调阶段(也称为下游任务训练):在预训练完成后,模型会被应用到具体的NLP任务中,如文本分类、机器翻译、问答系统等。在这个阶段,模型会使用有标签的数据进行微调,以适应特定任务的需求。通过微调,模型能够学习到与任务相关的特定知识,并进一步提高在该任务上的性能。 GPT模型的优势在于其强大的生成能力和对上下文信息的捕捉能力。这使得GPT模型在自然语言生成、文本摘要、对话系统等领域具有广泛的应用前景。同时,GPT模型也面临一些挑战,如计算资源消耗大、训练时间长等问题。为了解决这些问题,研究人员不断提出新的优化方法和扩展模型架构,如GPT-2、GPT-3等,以进一步提高模型的性能和效率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值