给出一棵树,对于每一个询问,给出2个节点,输出2个节点的距离。

输入中有字母,那个是没有用的,不用管。

思路:

0.选择编号为1的节点作为树的root

(注意:有些题的边是单向的,这时候我们要根据节点的入度来确定root,

    双向的话一般可以随意选择一个节点作为root)

1.dfs1,求出dep和pa[i][0]

2.初始化数组pa

3.节点(u,v)的权值为w

 把本来是边的权值w赋给u,v中dep较大的节点,

 cost[i]表示节点i的权值为cost[i]

 先初始化:cost[root]=0

4.dfs2,求每一个节点到root的距离dis[i]

5.查询:dis(u,v)=dis[u]+dis[v]-2*dis[lca(u,v)];

 #include<cstdio>
#include<cstring> using namespace std; const int maxn=+;
const int inf=0x3f3f3f3f; inline int swap(int &x,int &y)
{
x^=y;
y^=x;
x^=y;
} struct Edge
{
int to,next;
};
Edge edge[maxn<<];
int head[maxn];
int tot=;
int cost[maxn];
int dis[maxn];
int pa[maxn][];
int dep[maxn];
int e[maxn][]; void init()
{
memset(head,-,sizeof head);
tot=;
memset(dep,,sizeof dep);
memset(pa,-,sizeof pa);
} void addedge(int u,int v)
{
edge[tot].to=v;
edge[tot].next=head[u];
head[u]=tot++;
} void dfs1(int u)
{
for(int i=head[u];~i;i=edge[i].next)
{
int v=edge[i].to;
if(!dep[v])
{
dep[v]=dep[u]+;
pa[v][]=u;
dfs1(v);
}
}
} void init_pa(int n)
{
for(int j=;(<<j)<=n;j++)
{
for(int i=;i<=n;i++)
{
if(pa[i][j-]!=-)
pa[i][j]=pa[pa[i][j-]][j-];
}
}
} void dfs2(int u,int pre)
{
for(int i=head[u];~i;i=edge[i].next)
{
int v=edge[i].to;
if(v==pre)
continue;
dis[v]=dis[u]+cost[v];
dfs2(v,u);
}
} int query(int a,int b,int n)
{
int init_a=a;
int init_b=b;
if(dep[a]<dep[b])
swap(a,b);
int cnt;
for(cnt=;dep[a]-(<<cnt)>=;cnt++)
;
cnt--;
for(int j=cnt;j>=;j--)
{
if(dep[a]-(<<j)>=dep[b])
a=pa[a][j];
}
if(a==b)
return dis[init_a]+dis[init_b]-*dis[a];
for(int i=cnt;i>=;i--)
{
if(pa[a][i]!=-&&pa[a][i]!=pa[b][i])
{
a=pa[a][i];
b=pa[b][i];
}
}
return dis[init_a]+dis[init_b]-*dis[pa[a][]];
} void solve(int n)
{
dep[]=;
dfs1();
init_pa(n);
cost[]=;
dis[]=;
for(int i=;i<=n;i++)
{
if(dep[e[i][]]>dep[e[i][]])
swap(e[i][],e[i][]);
cost[e[i][]]=e[i][];
}
dfs2(,-); int m;
scanf("%d",&m);
for(int i=;i<=m;i++)
{
int u,v;
scanf("%d%d",&u,&v);
printf("%d\n",query(u,v,n));
}
return ;
} int main()
{
int n;
while(~scanf("%d",&n))
{
init();
int m;
scanf("%d",&m);
for(int i=;i<=m;i++)
{
int u,v,w;
char ch;
scanf("%d %d %d %c",&e[i][],&e[i][],&e[i][],&ch);
addedge(e[i][],e[i][]);
addedge(e[i][],e[i][]);
}
solve(n);
}
return ;
}

POJ 1986 DIstance Query LCA水题的更多相关文章

  1. POJ 1986 - Distance Queries - [LCA模板题][Tarjan-LCA算法]

    题目链接:http://poj.org/problem?id=1986 Description Farmer John's cows refused to run in his marathon si ...

  2. POJ.1986 Distance Queries ( LCA 倍增 )

    POJ.1986 Distance Queries ( LCA 倍增 ) 题意分析 给出一个N个点,M条边的信息(u,v,w),表示树上u-v有一条边,边权为w,接下来有k个询问,每个询问为(a,b) ...

  3. POJ 1986 Distance Queries LCA两点距离树

    标题来源:POJ 1986 Distance Queries 意甲冠军:给你一棵树 q第二次查询 每次你问两个点之间的距离 思路:对于2点 u v dis(u,v) = dis(root,u) + d ...

  4. poj 1986 Distance Queries LCA

    题目链接:http://poj.org/problem?id=1986 Farmer John's cows refused to run in his marathon since he chose ...

  5. POJ 1986 Distance Queries(LCA Tarjan法)

    Distance Queries [题目链接]Distance Queries [题目类型]LCA Tarjan法 &题意: 输入n和m,表示n个点m条边,下面m行是边的信息,两端点和权,后面 ...

  6. POJ 1986 Distance Queries / UESTC 256 Distance Queries / CJOJ 1129 【USACO】距离咨询(最近公共祖先)

    POJ 1986 Distance Queries / UESTC 256 Distance Queries / CJOJ 1129 [USACO]距离咨询(最近公共祖先) Description F ...

  7. poj 3080 Blue Jeans(水题 暴搜)

    题目:http://poj.org/problem?id=3080 水题,暴搜 #include <iostream> #include<cstdio> #include< ...

  8. poj 1986 Distance Queries 带权lca 模版题

    Distance Queries   Description Farmer John's cows refused to run in his marathon since he chose a pa ...

  9. POJ 1986 Distance Queries(Tarjan离线法求LCA)

    Distance Queries Time Limit: 2000MS   Memory Limit: 30000K Total Submissions: 12846   Accepted: 4552 ...

随机推荐

  1. scala言语基础学习七

    一.将函数赋值给变量 二.匿名函数 三.高阶函数 高阶函数好像调用不打印是看不到赋值 和普通函数区别 高阶函数的类型推断 reduce操作 相当于1*2*3*4*5*6*7*8*9 def getNa ...

  2. Oracle中sql的基本使用

    oracle数据库 select {distinct} * | 具体列  别名 from table {where 条件} {order by 排序字段1,排序字段2 asc | desc} 简单查询 ...

  3. distinct和group by

    distinct:同时查询两个字段,另外一个字段(不是distinct的那个字段,下例是tagid)需要多个值,如下                 group by:同时查询两个字段,另外一个字段( ...

  4. Linux实时监控工具Nmon使用

    官网:http://nmon.sourceforge.net/pmwiki.php?n=Main.HomePage 下载:http://sourceforge.net/projects/nmon/fi ...

  5. NLTK中的词性

    NOUN n,VERB v ,ADJ a, ADV r, ADJ_SAT s     NOUN: [('s', ''), ('ses', 's'), ('ves', 'f'), ('xes', 'x' ...

  6. mvn使用问题

    http://mirrors.ibiblio.org/maven2/org/apache/maven/archetypes/ http://blog.csdn.net/u011340807/artic ...

  7. JavaOOP 试题

    1) 以下属于OOP的特征有().   a)继承   b)封装   c)多态   d)隐藏   2) JavaOOP中的多态包括()   a) 方法重写 b) 方法重载   c) 方法隐藏 d) 以上 ...

  8. gnu-software

    gnu coreutils https://www.gnu.org/software/coreutils/manual/coreutils.html#toc_Printing-text 目录列表 ht ...

  9. PYTHON错误代码及解决办法

    (1)用sklearn进行逻辑回归时,建立完模型,由于要预测的数据量很大,无法一次全部预测,只能每次预测一个样本数据, 在每次以列表形式输入数据进行预测时出现: /Users/donganlan/an ...

  10. python 字典访问的三种方法

    定义字典 dic = {'a':"hello",'b':"how",'c':"you"} 方法一: for key in dic: prin ...