/*
在我还不知道LCA之前 暴力跑的SPFA
70分 三个点TLE
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
struct node
{
int u;
int t;
int pre;
};
node a[*+];
queue<int>q;
int n,qq,x[],num,head[],f[],dis[],sum;
void add(int from,int to)
{
num++;
a[num].pre=head[from];
a[num].u=to;
a[num].t=;
head[from]=num;
}
void SPFA()
{
int i,j;
for(j=;j<=qq-;j++)
{
memset(dis,/,sizeof(dis));
memset(f,,sizeof(f));
int s=x[j];
int v=x[j+];
q.push(s);
f[s]=;
dis[s]=;
do
{
int k=q.front();
q.pop();
f[k]=;
for(i=head[k];i;i=a[i].pre)
{
if(dis[a[i].u]>dis[k]+a[i].t)
{
dis[a[i].u]=dis[k]+a[i].t;
if(f[a[i].u]==)
{
q.push(a[i].u);
f[a[i].u]=;
}
}
}
}while(!q.empty());
sum=sum+dis[v];
}
}
int main()
{
int i,o,u;
cin>>n;
for(i=;i<=n-;i++)
{
cin>>o>>u;
add(o,u);
add(u,o);
}
cin>>qq;
for(i=;i<=qq;i++)
cin>>x[i];
SPFA();
cout<<sum;
}
/*
倍增LCA
将旅行路线两两拆开 求相邻两点的距离
即求他们到lca的距离和
这里用倍增法实现求距离 fa[i][j]表示i节点往上2^j层的节点是什么
因为1 2 4 8 16...做和可以表示所有的整数 所以保证覆盖整张图
先Dfs建图 顺面几下每个节点的所在层 以及fa[i][0] 的值
然后DP预处理fa数组
然后就是求到lca的距离了
这里我们求出只需要求出lca是谁 那么两点之间的最小距离就是
deep[p1]+deep[p2]-2*deep[anc] deep是深度
剩下的就仅仅是找lca是谁了
对于一组a ,b 如果他们在同一层的话 我们只需要同时向上移动他俩 知道a==b */
#include<iostream>
#include<cstdio>
#include<cstring>
#define maxn 30010
#define S 16
int n,m,num,head[maxn],fa[maxn][S+],deep[maxn],p1,p2,ans;
struct node
{
int u,v,pre;
}e[maxn*];
void Add(int from,int to)
{
num++;
e[num].u=from;
e[num].v=to;
e[num].pre=head[from];
head[from]=num;
}
void swap(int &a,int &b)
{
int t=a;a=b;b=t;
}
void init()
{
scanf("%d",&n);
int x,y;
for(int i=;i<=n-;i++)
{
scanf("%d%d",&x,&y);
Add(x,y);Add(y,x);
}
}
void get_fa()
{
for(int j=;j<=S;j++)
for(int i=;i<=n;i++)
fa[i][j]=fa[fa[i][j-]][j-];//数学方法展开就是fa[i][j]
}
void Dfs(int now,int from,int c)//得带每个点的所在层
{
fa[now][]=from;
deep[now]=c;
for(int i=head[now];i;i=e[i].pre)
if(e[i].v!=from)
Dfs(e[i].v,now,c+);
}
int get_same(int a,int t)//计算a往上t层是啥
{
for(int i=;i<=t;i++)
a=fa[a][];
return a;
}
int LCA(int a,int b)
{
if(deep[a]<deep[b])swap(a,b);//保证a深度大
a=get_same(a,deep[a]-deep[b]);//得到a向上deep[a]-deep[b]层是谁 即a的与b同层的祖先是谁
if(a==b)return a;//如果汇聚到一个点 就不用往上了
for(int i=S;i>=;i--)//这里有套路 从最大值开始循环 一开始 fa[a][i] fa[b][i]一定是相等的
//因为此时位于他们lca之上 然后往下 这里可以覆盖每一层
if(fa[a][i]!=fa[b][i])
{
a=fa[a][i];
b=fa[b][i];
}
return fa[a][];
}
int main()
{
init();
Dfs(,,);
get_fa();
scanf("%d%d",&m,&p1);
for(int i=;i<=m-;i++)
{
scanf("%d",&p2);
int anc=LCA(p1,p2);
ans+=deep[p1]+deep[p2]-*deep[anc];
p1=p2;
}
printf("%d\n",ans);
return ;
}

codevs 1036 商务旅行 (倍增LCA)的更多相关文章

  1. 倍增法-lca codevs 1036 商务旅行

    codevs 1036 商务旅行  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond 题目描述 Description 某首都城市的商人要经常到各城镇去做生意 ...

  2. CodeVs.1036 商务旅行 ( LCA 最近公共祖先 )

    CodeVs.1036 商务旅行 ( LCA 最近公共祖先 ) 题意分析 某首都城市的商人要经常到各城镇去做生意,他们按自己的路线去做,目的是为了更好的节约时间. 假设有N个城镇,首都编号为1,商人从 ...

  3. codevs——1036 商务旅行

    1036 商务旅行  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond 题解  查看运行结果     题目描述 Description 某首都城市的商人要经常 ...

  4. codevs 1036 商务旅行(Targin求LCA)

    传送门 Description 某首都城市的商人要经常到各城镇去做生意,他们按自己的路线去做,目的是为了更好的节约时间. 假设有N个城镇,首都编号为1,商人从首都出发,其他各城镇之间都有道路连接,任意 ...

  5. CODEVS 1036 商务旅行

    题目描述 Description 某首都城市的商人要经常到各城镇去做生意,他们按自己的路线去做,目的是为了更好的节约时间. 假设有N个城镇,首都编号为1,商人从首都出发,其他各城镇之间都有道路连接,任 ...

  6. 【最近公共祖先】【树链剖分】CODEVS 1036 商务旅行

    树链剖分求lca模板.O(log(n)),就是不倍增嘛~ #include<cstdio> #include<algorithm> using namespace std; # ...

  7. 【最近公共祖先】【块状树】CODEVS 1036 商务旅行

    在线块状树LCA模板. #include<cstdio> #include<vector> #include<algorithm> #include<cmat ...

  8. codevs1036商务旅行(LCA)

    1036 商务旅行  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond 题解       题目描述 Description 某首都城市的商人要经常到各城镇去做 ...

  9. CODEVS——T 1036 商务旅行

    http://codevs.cn/problem/1036/  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond 题解       题目描述 Descript ...

随机推荐

  1. HashMap在Android和Java中的不同实现

    起因 今天在项目中遇到一个很"奇葩"的问题.情况大致是这样的:Android终端和服务器(Spring),完全相同的字符串键值对放入HashMap中竟然顺序不一样,这直接导致了服务 ...

  2. 如何重载ComboBox 使其下拉按钮(带下箭头的)和下拉列表的垂直滚动条的宽度改变?(自绘ComboBox) [转]

    原文地址:http://bbs.csdn.net/topics/390135022 http://blog.csdn.net/scsdn/article/details/4363299 想使用winf ...

  3. Journey of Android for Mac

    下了决心要学Java,几个同事都建议我去学Android,自己觉得能做点应用放手机上玩玩也比较有动力. 沈逸有篇文章里面写道: 搞C的看不起搞C++的. 搞C++的看不起搞java的. 搞java的看 ...

  4. jQuery折叠风琴

    这个效果用jQuery做是很方便的,根本不需要搞得很复杂. 网上有些效果DEMO不仅用了jQuery还引用一两个封装文件,真是匪夷所思. 最初想到了toggle: jQuery(document).r ...

  5. #include< >和#include""的区别

    Answer 1:#include 会将指定文件的内容插入到源程序文件中.当使用的格式时,编译器会从环境变量INCLUDE所指定的路径中寻找file-name 文件,如果没有定义INCLUDE,C 编 ...

  6. 工程师必知ZigBee技术问答精华汇总

    本文是关于ZigBee技术的一些基础知识.行业应用方面的精华汇总.希望通过本文的分析,能让大家对ZigBee技术的起源.发展.特点.前景及其在通信网络中的相关应用有全面直观的了解. 1.基础知识篇 Q ...

  7. BAT 批处理实现循环备份N天文件夹

    @echo off set today=%date:~0,4%%date:~5,2%%date:~8,2% xcopy  /E /I E:\aaa e:\test\%today% for /f &qu ...

  8. oracle 表的管理(数据类型,表创建删除,数据CRUD 操作)

    表名和列的命名规则

  9. VS2010如何生成release文件

    点击生成-->配置管理器-->活动解决方案配置下拉菜单中选择release就行了,最后再编译一下就在相应的目录下生成了

  10. c++转换构造函数和类型转换函数

    看stl源码时,有一段代码感觉很奇怪 iterator begin() { return (link_type)((*node).next); } iterator和link_type是两种不同类型, ...