题目链接:https://vijos.org/p/1460

    http://oj.fjaxyz.com:3389/problem.php?id=223

我不禁开始怀疑,这,真的是最近公共祖先的题吗,我是从一个讲解LCA的博客里找到这道题的,然后我就乖乖的用了可爱的LCA倍增,然后我就更加愉快的TLE了。

【思路】

判断u,v 的最近公共祖先是不是u,如果是,就加上这条路线。。。

判断u,v的最近公共祖先是不是u,TLE的代码是用倍增算法做的这个,但是啊,其实我们换一种说法就是判断u是不是v的祖先

那么这就简单了,想想LCA的离线做法tarjan,里面的dfn数组,储存的是i点的dfs序号,然后实质上其实是前序遍历序号

怎么判断u是v的祖先?刚刚才提到前序遍历,那我想想后序遍历,前序是根左右,后序是左右根,那么意思就是根在前序是比叶节点序号小,在后序是比叶节点序号大

于是我们储存数组begn[] ed[]储存点的前序序号和后序序号,如果begn[u]<begn[v]&&ed[u]>ed[v]说明u是v的祖先

解决了这个问题,接下来就是求距离,我们储存数组dis表示点i到根节点的距离,

所以u,v距离就是dis[u]+dis[v]-2*dis[lca(u,v)],由于这题满足条件是u为v的祖先,所以距离简化为dis[v]-dis[u]

LCA倍增算法

 #include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<stack>
#include<queue>
#include<cstdlib>
#define maxn 10005
#define ll long long
using namespace std; struct node{
int u,v;ll w;int nxt;
}e[maxn]; int head[maxn],n,m,f[maxn][];
ll dis[maxn],ans;
int cnt,vis[maxn],dep[maxn]; int tot;
void adde(int u,int v,int w){
e[tot]=(node){u,v,w,head[u]};
head[u]=tot;tot++;
} void build(int u){
for(int i=head[u];i!=-;i=e[i].nxt){
int v=e[i].v;
if(!vis[v]){
f[v][]=u;
dis[v]=dis[u]+e[i].w;
dep[v]=dep[u]+;
vis[v]=;
build(v);
}
}
} void first(){
for(int j=;j<=;j++){
for(int i=;i<=n;i++){
f[i][j]=f[f[i][j-]][j-];
}
}
} int up(int x,int d){
for(int i=;i<=d;i++)
x=f[x][];
return x;
} int find(int x,int y){
if(dep[x]<dep[y])swap(x,y);
if(dep[x]!=dep[y]){
int dd=dep[x]-dep[y];
x=up(x,dd);
}
if(x==y){return x;}
for(int j=;j>=;j--){
if(f[x][j]!=f[y][j]){
x=f[x][j];y=f[y][j];
}
}
return f[x][];
} ll len(int u,int v){
return dis[v]-dis[u];
} int main(){
memset(head,-,sizeof(head));
scanf("%d%d",&n,&m);
for(int i=;i<n;i++){
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
adde(u,v,w);
}
build();
first();
for(int i=;i<=m;i++){
int u,v;
scanf("%d%d",&u,&v);
int lca=find(u,v);
if(lca==u){ans+=len(u,v);cnt++;}
}
printf("%d\n%lld",cnt,ans);
}

倍增(TLE)

运用前序后序的dfs算法

 #include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<stack>
#include<queue>
#include<cstdlib>
#define maxn 10005
using namespace std; struct node{
int u,v;long long w;int nxt;
}e[maxn]; int head[maxn],n,m;
int cnt,vis[maxn];
int begn[maxn],ed[maxn];
long long ans,dis[maxn]; int tot;
void adde(int u,int v,long long w){
e[tot]=(node){u,v,w,head[u]};
head[u]=tot;tot++;
} int num,hehe;
void build(int u){
num++;begn[u]=num;
for(int i=head[u];i!=-;i=e[i].nxt){
int v=e[i].v;
if(!vis[v]){;
dis[v]=dis[u]+e[i].w;
vis[v]=;
build(v);
}
}
hehe++;ed[u]=hehe;
} int main(){
memset(head,-,sizeof(head));
scanf("%d%d",&n,&m);
for(int i=;i<n;i++){
int u,v;long long w;
scanf("%d%d%lld",&u,&v,&w);
adde(u,v,w);
}
build();
for(int i=;i<=m;i++){
int u,v;
scanf("%d%d",&u,&v);
if(begn[u]<=begn[v]&&ed[u]>=ed[v]){
ans+=dis[v]-dis[u];cnt++;
}
}
printf("%d\n%lld",cnt,ans);
}

AC于vijos

然后问题就来了,这个在vijos上AC的代码在meto code上还是WA了,我已经放弃了,因为meto code不提供错误数据也不告诉我错了几组,所以我最终还是没有在meto code上成功

[vijos1460&Metocode P223]拉力赛<LCA>的更多相关文章

  1. 算法笔记--lca倍增算法

    算法笔记 模板: vector<int>g[N]; vector<int>edge[N]; ][N]; int deep[N]; int h[N]; void dfs(int ...

  2. 最近公共祖先LCA(Tarjan算法)的思考和算法实现

    LCA 最近公共祖先 Tarjan(离线)算法的基本思路及其算法实现 小广告:METO CODE 安溪一中信息学在线评测系统(OJ) //由于这是第一篇博客..有点瑕疵...比如我把false写成了f ...

  3. lca(最近公共祖先(离线))

    转自大佬博客 : https://www.cnblogs.com/JVxie/p/4854719.html   LCA 最近公共祖先 Tarjan(离线)算法的基本思路及其算法实现 首先是最近公共祖先 ...

  4. Vijos——T1406 拉力赛

    https://vijos.org/p/1460 描述 车展结束后,游乐园决定举办一次盛大的山道拉力赛,平平和韵韵自然也要来参加大赛. 赛场上共有n个连通的计时点,n-1条赛道(构成了一棵树).每个计 ...

  5. 最近公共祖先LCA(Tarjan算法)的思考和算法实现——转载自Vendetta Blogs

    LCA 最近公共祖先 Tarjan(离线)算法的基本思路及其算法实现 小广告:METO CODE 安溪一中信息学在线评测系统(OJ) //由于这是第一篇博客..有点瑕疵...比如我把false写成了f ...

  6. LCA 最近公共祖先 Tarjan(离线)算法的基本思路及其算法实现

    首先是最近公共祖先的概念(什么是最近公共祖先?): 在一棵没有环的树上,每个节点肯定有其父亲节点和祖先节点,而最近公共祖先,就是两个节点在这棵树上深度最大的公共的祖先节点. 换句话说,就是两个点在这棵 ...

  7. 【模板】Tarjian求LCA

    概念 公共祖先,就是两个节点在这棵树上深度最大的公共的祖先节点 举个例子吧,如下图所示4和5的最近公共祖先是2,5和3的最近公共祖先是1,2和1的最近公共祖先是1. 算法 常用的求LCA的算法有:Ta ...

  8. BZOJ 3083: 遥远的国度 [树链剖分 DFS序 LCA]

    3083: 遥远的国度 Time Limit: 10 Sec  Memory Limit: 1280 MBSubmit: 3127  Solved: 795[Submit][Status][Discu ...

  9. BZOJ 3626: [LNOI2014]LCA [树链剖分 离线|主席树]

    3626: [LNOI2014]LCA Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2050  Solved: 817[Submit][Status ...

随机推荐

  1. mac中如何复制拷贝文件或文件夹的路径

    copy path in Mac 首先打开 automator(自动操作) 然后 最后command+s保存,命名为copy path. 然后随便找个文件右击,选择服务,再选择 copy path , ...

  2. 前端每日实战:85# 视频演示如何用纯 CSS 创作一个小球反弹的动画

    效果预览 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/OwWROO 可交互视频 此视频是可 ...

  3. Pytorch-Tensor基本操作

    (此文为个人学习pytorch时的笔记,便于之后的查询) Tensor基本操作 创建tensor: ​ 1.numpy向量转tensor: a=np.array([2,2,2]) b=torch.fr ...

  4. 机器学习基础——简单易懂的K邻近算法,根据邻居“找自己”

    本文始发于个人公众号:TechFlow,原创不易,求个关注 今天的文章给大家分享机器学习领域非常简单的模型--KNN,也就是K Nearest Neighbours算法,翻译过来很简单,就是K最近邻居 ...

  5. MapReduce 简单数据统计

    1. 准备数据源 摘录了一片散文,保存格式为utf-8 2. 准备环境 2.1 搭建伪分布式环境 https://www.cnblogs.com/cjq10029/p/12336446.html 上传 ...

  6. 02 VMware下载与安装

    一.虚拟机的下载 1.进入官方网站 vmware Workstation 官方网站: https://www.vmware.com/cn.html 2.根据操作系统选择合适的产品,在这里以Window ...

  7. ASP.NET Core身份认证服务框架IdentityServer4 介绍

    IdentityServer4是ASP.NET Core 2的OpenID Connect和OAuth 2.0框架.它可以在您的应用程序中提供以下功能: 它使你的应用程序具有如下特点: 认证即服务 适 ...

  8. 【字节校招】【实习】【内推】字节跳动春招(校招或实习均可)以及日常实习内推ing

    本人是年前刚刚入职抖音的应届生,职业认证还未来的级更改,但是这些都不重要.重要的是我们不能错过优秀的你~ 字节跳动的相关福利我就不介绍了,技术实习生是400/天,房补是1500/月,三餐免费,下午茶, ...

  9. 安装archlinux的另辟蹊径的命令及心得

    先说说我为什么开始入坑archlinux的吧,我最喜欢这个系统的一点就是简洁,DIY程度高,可以定制真正属于自己的专用系统.(像gentoo的话,就为了日常使用也没必要那么折腾,除非你是想在折腾的过程 ...

  10. java面试题汇总四

    第三部分 Java SE基础 3.1 java多线程 3.1.1 线程的实现方式,怎么启动线程怎么区分线程? 1.线程的实现方式: 有 4 种方式可以用来创建线程: 2.继承 Thread 类   2 ...