这道题与之前那两道模板题不同的是,路径有了权值,而且边是双向的,root已经给出来了,就是1,(这个地方如果还按之前那样来计算入度是会出错的。数据里会出现多个root。。。数据地址可以在poj的discuss板块看到)。两个节点之间的距离,可以这样处理:先处理出每个节点i到根的距离dist[i],则节点a,b之间的距离就是dist[a]+dist[b]-2*dist[LCA(a,b)],或者是在LCA的过程中加一个形式变量来传递距离值(目测这样效率会更高)。我一开始是想的仅传递每层的距离,具体怎样记不清了,结果样例就华丽丽地wa了。个人认为这个题目描述真心不爽。最后那个方向字符在这个题中没用。

#include<cstdio>
#include<vector>
#include<string>
//sba,just predeal the distance between every node and the root.and the dist[u][v]=dist[u][root]+dist[v][root]-2*dist[x][root]
using namespace std;
;
;
;
struct node{
    int v,dis;
    node(){v=;dis=;}
};
int ansque[MAXQUERY];
int father[MAXN];//i's ancestor and the distance between the son and the ancestor
vector<node>map[MAXN];
vector<node>query[MAXN];
int dist[MAXN];//i -->root
bool visit[MAXN],visit2[MAXN];
int getfather(int v){
    if(father[v]==v)return v;
    return father[v]=getfather(father[v]);
}
void aunion(int u,int v){
    int fu=father[u],fv=father[v],di;
    father[fv]=fu;
}
void LCA(int id,int distance){
    int len=map[id].size();
    int son;
    visit2[id]=;
    dist[id]=distance;
    ;i<len;i++){
        son=map[id][i].v;
        if(!visit2[son]){
            LCA(son,distance+map[id][i].dis);
            aunion(id,son);
        }

    }
    visit[id]=true;
    len=query[id].size();
    ;i<len;i++){
        son=query[id][i].v;
        if(visit[son]){
            ansque[query[id][i].dis]=dist[id]+dist[son]-*dist[father[getfather(son)]];
            //mark
        }
    }
}
int main(){
    while(scanf("%d%d",&n,&m)!=EOF){//attention
        //at the begining,we'd better to initialize all the vars
        int x,y,l;
        char a;
        node b;
        ;i<=n;i++){
            map[i].clear();//the mothod of the initialization of queue
            query[i].clear();
            father[i]=i;
            visit[i]=;
            visit2[i]=;
            ansque[i]=;
            dist[i]=;
        }

        while(m--){
            scanf("%d %d %d %c",&x,&y,&l,&a);//only father
            b.v=y;b.dis=l;
            map[x].push_back(b);
            b.v=x;
            map[y].push_back(b);
        }
        scanf("%d",&m);
        node tmp2;
        ;i<m;i++){
            scanf("%d%d",&x,&y);
            tmp2.v=y;tmp2.dis=i;
            query[x].push_back(tmp2);
            tmp2.v=x;
            query[y].push_back(tmp2);
        }
        LCA(,);
        ;i<m;i++)
            printf("%d\n",ansque[i]);
    }

    ;
}

POJ1986 DistanceQueries 最近公共祖先LCA 离线算法Tarjan的更多相关文章

  1. LCA(最近公共祖先)离线算法Tarjan+并查集

    本文来自:http://www.cnblogs.com/Findxiaoxun/p/3428516.html 写得很好,一看就懂了. 在这里就复制了一份. LCA问题: 给出一棵有根树T,对于任意两个 ...

  2. 近期公共祖先(LCA)——离线Tarjan算法+并查集优化

    一. 离线Tarjan算法 LCA问题(lowest common ancestors):在一个有根树T中.两个节点和 e&sig=3136f1d5fcf75709d9ac882bd8cfe0 ...

  3. 最近公共祖先 LCA 倍增算法

          树上倍增求LCA LCA指的是最近公共祖先(Least Common Ancestors),如下图所示: 4和5的LCA就是2 那怎么求呢?最粗暴的方法就是先dfs一次,处理出每个点的深度 ...

  4. LCA离线算法Tarjan详解

    离线算法也就是需要先把所有查询给保存下来,最后一次输出结果. 离线算法是基于并查集实现的,首先就是初始化P[i] = i. 接下来对于每个点进行dfs: ①首先判断是否有与该点有关的查询,如果当前该点 ...

  5. LCA离线算法Tarjan的模板

    hdu 2586:题意:输入n个点的n-1条边的树,m组询问任意点 a b之间的最短距离 思路:LCA中的Tarjan算法,RMQ还不会.. #include <stdio.h> #inc ...

  6. 距离LCA离线算法Tarjan + dfs + 并查集

    距离B - Distance in the Tree 还是普通的LCA但是要求的是两个节点之间的距离,学到了一些 一开始我想用带权并查集进行优化,但是LCA合并的过程晚于离线计算的过程,所以路径长度会 ...

  7. HDU 2874 LCA离线算法 tarjan算法

    给出N个点,M条边.Q次询问 Q次询问每两点之间的最短距离 典型LCA 问题   Marjan算法解 #include "stdio.h" #include "strin ...

  8. LCA(最近公共祖先)——离线 Tarjan 算法

    tarjan算法的步骤是(当dfs到节点u时):1 在并查集中建立仅有u的集合,设置该集合的祖先为u1 对u的每个孩子v:   1.1 tarjan之   1.2 合并v到父节点u的集合,确保集合的祖 ...

  9. [模板] 最近公共祖先/lca

    简介 最近公共祖先 \(lca(a,b)\) 指的是a到根的路径和b到n的路径的深度最大的公共点. 定理. 以 \(r\) 为根的树上的路径 \((a,b) = (r,a) + (r,b) - 2 * ...

随机推荐

  1. 使用Animation实现Button的透明度Opacity变化

    接着之前的使Button的Content变化的例子,这里给出使Button的透明度变化的写法. 前台写法: 后台写法: 效果图:Opacity的值正在变小 效果还不错,前台是用Blend生成的,后台的 ...

  2. AIX性能监控topas命令的详细解析

    执行topas命令后如图所示: #topas 区域1:反映CPU使用率和工作状况  Kernel:操作系统的内核占用的CPU时间比率. 操作系统作为基础软件,为应用程序支持和服务的同时,本身的运行也需 ...

  3. SQLserver Delete from where 与Oracle delete from where 的差异

    1.SQLserver 版本: select @@version; Microsoft SQL Server 2012 (SP1) - 11.0.3128.0 (X64) Dec 28 2012 20 ...

  4. Winform上传下载文件代码

    using System; using System.Collections.Generic; using System.Text; using System.Net; using System.IO ...

  5. QUOTENAME函数的用法

    quotename函数的语法为:quotename('expression1','expression2') expression1:指的是需要被特殊处理的字符 expression2:例如{}.[] ...

  6. Cannot resolve the collation conflict between "SQL_Latin1_General_CP1_CI_AS" and "Latin1_General_100_CI_AS" in the equal to operation.

    ErrorMessage Cannot resolve the collation conflict between "SQL_Latin1_General_CP1_CI_AS" ...

  7. EF中使用Select new 方法中字段值替换的问题

    前提需要替换查询得到的List当中的某个字段的值,替换规则有一个mapping关系 尝试代码 有问题 无法获取任何数据 /// <summary> /// 获取Treegrid的List ...

  8. AVPlayer的基本使用

    2014-5-7 06:46| 发布者: admin| 查看: 437| 评论: 0   摘要: 在iOS开发中,播放视频通常有两种方式,一种是使用MPMoviePlayerController(需要 ...

  9. Struts之ForwardAction

    在Struts中,通过action跳转jsp,但是有时希望仅仅只是跳转页面,而不需要action,这时可以用ForwardAction. 定义一个仅仅是跳转的ForwardAction如下: < ...

  10. curPos和tgtPos

    curpos tgtpos 乍一看以为是当前位置和目标位置,但在项目里面这两个位置有点坑 当客户端玩家移动或者AI里面的位置,会把获得的位置付给tgtpos 而以前的tgtpos会付给curpos 所 ...