[LCA]二月的最后一天来搞事情吧

先发模版题

codevs 2370 小机房的树

poj 1986 Distance Queries

poj 1330 Nearest Common Ancestors

感谢机房大佬xqmmcqs的代码

Tarjan版   http://www.cnblogs.com/xqmmcqs/p/5952293.html

树上倍增版  http://www.cnblogs.com/xqmmcqs/p/5954097.html

#include<cstdio>
#define MAXN
#define MAXQ
int n,Q,heade[MAXN],headq[MAXN],fa[MAXN],lca[MAXQ],dis[MAXN],cnt;
bool vis[MAXN];
struct edge
{
    int v,next,val;
}e[MAXN*2];
struct query
{
    int u,v,next;
}q[MAXQ*2];
void adde(int x,int y,int z)
{
    e[++cnt].v=y;
    e[cnt].next=heade[x];
    heade[x]=cnt;
    e[cnt].val=z;
}
void addq(int x,int y)
{
    q[++cnt].u=x;
    q[cnt].v=y;
    q[cnt].next=headq[x];
    headq[x]=cnt;
}
int getfa(int x)//并查集路径压缩
{
    return fa[x]=x==fa[x]?x:getfa(fa[x]);
}
int getdis(int i)//计算路径长度
{
    return dis[q[i<<1].u]+dis[q[i<<1].v]-2*dis[lca[i]];
}
void Tarjan(int u)
{
    fa[u]=u;
    vis[u]=true;
    for(int i=heade[u];i;i=e[i].next)
    {
        int v=e[i].v;
        if(!vis[v])
        {
            dis[v]=dis[u]+e[i].val;
            Tarjan(v);
            fa[v]=u;
        }
    }
    for(int i=headq[u];i;i=q[i].next)//处理询问
    {
        int v=q[i].u==u?q[i].v:q[i].u;
        if(vis[v])lca[i>>1]=getfa(fa[v]);
    }
}
int main()
{
    scanf("%d",&n);
    int x,y,z;
    for(int i=1;i<n;i++)
    {
        scanf("%d%d%d",&x,&y,&z);
        adde(x,y,z);
        adde(y,x,z);
    }
    cnt=1;
    scanf("%d",&Q);
    for(int i=1;i<=Q;i++)
    {
        scanf("%d%d",&x,&y);
        addq(x,y);
        addq(y,x);
    }
    Tarjan(1);
    for(int i=1;i<=Q;i++)
    {
        printf("%d\n",getdis(i));
    }
    return 0;
}

xqmmcqs Tarjan

#include<cstdio>
#include<algorithm>
using namespace std;
struct edge
{
    int v,next,val;
}e[100005];
int n,m,heads[50005],fa[17][50005],dis[50005],dep[50005],cnt;
void add(int u,int v,int val)
{
    e[++cnt].next=heads[u];
    heads[u]=cnt;
    e[cnt].v=v;
    e[cnt].val=val;
}
void dfs(int u)//预处理dep和fa[0][j]
{
    for(int i=heads[u];i;i=e[i].next)
    {
        if(e[i].v!=fa[0][u])
        {
            dep[e[i].v]=dep[u]+1;
            fa[0][e[i].v]=u;
            dis[e[i].v]=dis[u]+e[i].val;
            dfs(e[i].v);
        }
    }
}
int LCA(int u,int v)
{
    if(dep[u]>dep[v])swap(u,v);
    for(int i=16;~i;i--)
        if(dep[fa[i][v]]>=dep[u])
            v=fa[i][v];
    if(u==v)return u;
    for(int i=16;~i;i--)
        if(fa[i][u]!=fa[i][v])
        {
            u=fa[i][u];
            v=fa[i][v];
        }
    return fa[0][u];
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<n;i++)
    {
        int x,y,z;
        scanf("%d%d%d",&x,&y,&z);
        add(x,y,z);
        add(y,x,z);
    }
    dep[1]=fa[0][1]=1;
    dfs(1);
    for(int i=1;i<=16;i++)
        for(int j=1;j<=n;j++)
            fa[i][j]=fa[i-1][fa[i-1][j]];
    scanf("%d",&m);
    while(m--)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        printf("%d\n",dis[x]+dis[y]-2*dis[LCA(x,y)]);//两点之间路径长度
    }
    return 0;
}

xqmmcqs 树上倍增

#include <bits/stdc++.h>
using namespace std;
#define Maxn 50005
#define Maxq 75005
int cnt=0,lan[Maxn],laq[Maxq],fa[Maxn],vis[Maxn],dis[Maxn],lca[Maxq];
struct edge
{
    int u,v,n,c;
}e[Maxn<<1];
struct que
{
    int u,v,n;
}q[Maxq<<1];
void adde(int u,int v,int c)
{
    e[++cnt]=(edge){u,v,lan[u],c},lan[u]=cnt;
    e[++cnt]=(edge){v,u,lan[v],c},lan[v]=cnt;
}
void addq(int x,int y)
{
    q[++cnt]=(que) {x,y,laq[x]},laq[x]=cnt;
    q[++cnt]=(que) {y,x,laq[y]},laq[y]=cnt;
}
int getfa(int x)
{
    return fa[x]=x==fa[x]?x:getfa(fa[x]);
}
void tarjan(int u)
{
    fa[u]=u;
    vis[u]=1;
    for (int i=lan[u];i;i=e[i].n)
    {
        int v=e[i].v;
        if (vis[v]==0)
        {
            dis[v]=dis[u]+e[i].c;
            tarjan(v);
            fa[v]=u;

        }
    }
    for (int i=laq[u];i;i=q[i].n)
    {
        int v=q[i].v;
        if (vis[v]) lca[i>>1]=getfa(fa[v]);
    }
}
int getdis (int i)
{
    return dis[q[i<<1].u]+dis[q[i<<1].v]-(dis[lca[i]]<<1);
}
int main()
{
    int n,m;
    scanf ("%d",&n);
    for (int i=1;i<n;i++)
    {
        int u,v,c;
        scanf ("%d %d %d",&u,&v,&c);
        adde(u,v,c);
    }
    scanf ("%d",&m);
    cnt=1;
    for (int i=1;i<=m;i++)
    {
        int x,y;
        scanf ("%d %d",&x,&y);
        addq(x,y);
    }
    tarjan (1);
    for (int i=1;i<=m;i++)
    {
        printf ("%d\n",getdis(i));
    }
}

一些玄学的事情

xqmmcqs Tarjan版本中第52行

int v=q[i].u==u?q[i].v:q[i].u;

可以直接替换成

int v=q[i].v;

以及

在codevs测2370小机房的树时,多开5个,大数据莫名其妙WA掉,多开10个就好了

以上

一七年二月的最后一天还有三个小时就结束了

准备搞点事情了

立一个flag好了

在一七年三月的第一天搞并查集,嗯,可能吧



最后一行献给可爱的男孩子们



[LCA]二月的最后一天来搞事情吧

时间: 2024-12-19 23:59:51

[LCA]二月的最后一天来搞事情吧的相关文章

谷歌搞事情:最先被AI淘汰的,居然是做AI的?

坊间流传着这么一个说法:谷歌想回中国,必须靠AI:而靠AI回中国,必须搞个大事情.于是,上周四的晚上李飞飞发布了一篇博客,然后连着发了三条推特,宣布一个叫AutoML的AI产品启动了. 一夜之间,中国的科技媒体就爆炸了,空气中似乎回荡着那一句话:搞事情了搞事情了搞事情了-- AutoML到底是不是跟谷歌的中国战略有关,我们不做讨论.这里希望帮大家搞清楚的,是这个AutoML到底要搞什么事情. 按照谷歌云AI项目首席科学家李飞飞的说法,AutoML的目标是降低开发者.研究者和企业群体使用人工智能相

苹果又要搞事情了 KlipC紧随其后 苹果官宣了:9月10日10点(当地时间),在位于美国加州的A

苹果又要搞事情了 KlipC紧随其后 苹果官宣了:9月10日10点(当地时间),在位于美国加州的Apple Park举行2019年的秋季发布会.新一波抢钱利器在路上了....新Iphone, Macbook Pro,Apple Watch Series 5.....各大媒体已经开始了对苹果新产品的概念性预测及新款机型的技术性预测.更甚有网友开始调侃今年苹果的Logo.如下图: 看到这个,你想到了什么?KlipC真的不得不佩服这些网友们的想象里,请看下图: 不要笑,看到这几个网友的调侃后,真的觉得

今天搞事情,angularjs项目实例分析

今天呢,我要学习的这个angularjs项目的github地址为:https://github.com/monw3c/angularjs_pingan 可能呢?这不是最好的angularjs实例,但是呢还是好好分析其中是什么一个原理 好了开始了,首先你就这个项目git clone到本地 1.打开到 angularjs_pingan所在的文件夹 2.建个本地服务,这里我用到的是http-server npm install http-server --save-dev 接着http-server

搞事情:linux下安装迅雷和qq。(迅雷接近完美,qq能记住密码,不能视频) 转载

只关心软件下载地址和安装方法的话可以直接下拉到文末"核心内容"处 一.闲聊 我们知道,linux桌面版的普及总是受着很大的制约,其中一个不得不提的原因便是商业软件的缺失,很多我们难以诀别的驱动和商业软件都没有linux原版的(如QQ.迅雷.百度云等),使得我们在使用linux发行版的时候总是遇到诸多的不便.同时,由于linux的开源特性,以linux为核心的发行版可谓是林林总总,仅仅是我所接触的linux发行版便不下20个.不同的linux发行版总是有着不同的特色,但是毫无疑问的是,每

周六搞事情,微信小程序开发文档已放出!

程序员们,你们有事干了! 个人感觉不管是什么形式的UI技术,都无法决定一个产品的生死,核心还是服务和模式的创新. 某些方面和ApiCloud好像,但发展前景远远胜过ApiCloud. 微信小程序可以为中小企业新开发的程序降低开发成本. 未来几年,会影响很多人的人生轨迹,部分人可能工作要不好找了. 想起多年前那句话,App已死,服务永生.  

codevs 5958 无x(搞事情)

这个名字我很想吐槽 这个题目就特别厉害了! 入下: 5958 无 时间限制: 1 s 空间限制: 1000 KB 题目等级 : 大师 Master 题目描述 Description 无 输入描述 Input Description 无 输出描述 Output Description 无 样例输入 Sample Input 无 样例输出 Sample Output 无 数据范围及提示 Data Size & Hint 无 分类标签 Tags 点此展开 代码够简单! 1 int main() 2 {

08 r2系统远程端口搞事情

总结一下思路:先测试下服务器本身.就是在本机mstsc是否能打开界面,然后输入本机IP,看提示的错误信息来判断问题,无法连接,就说明服务没有开启.如果判断远程服务是正常后,就在局域网里找到机器,进行Mstsc来远程.若无法连接的错误,查看2008是不是防火墙阻止了服务,不管是第三方的,还是本机内置的.最后可以判断为远程服务挂了,需要安装远程桌面授权(RD 授权),但装到最后发现该服务需要收费,RD服务安装文档链接为:http://www.jb51.net/os/windows/win2008/1

【51CTO学院】秒杀搞事情!名利双收的好机会来啦!

各位老师大家好!51CTO学院的秒杀活动开始至今,受到了越来越多的学员喜爱.目前每天浏览秒杀活动的学员多达上千人,部分讲师每个月单从秒杀中获得的收入就超过10000元. 但是由此需要的秒杀课程也在增多,为了方便老师申请,同时也减少运营人员的操作成本. 老师们可以通过以下表单进行自主申请,提供课程链接及折扣即可!http://s8vbd1g5aihqr4r5.mikecrm.com/lD7WewP 我们收到课程筛选后,将由技术统一加入秒杀库中.需要注意:已经在秒杀库中的课程,或被移除秒杀库中的课程

2588. Count on a tree【主席树+LCA】

Description 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权.其中lastans是上一个询问的答案,初始为0,即第一个询问的u是明文. Input 第一行两个整数N,M. 第二行有N个整数,其中第i个整数表示点i的权值. 后面N-1行每行两个整数(x,y),表示点x到点y有一条边. 最后M行每行两个整数(u,v,k),表示一组询问. Output M行,表示每个询问的答案.最后一个询问不输出换行符 S