codevs 1036 商务旅行 (倍增LCA)
/*
在我还不知道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)的更多相关文章
- 倍增法-lca codevs 1036 商务旅行
codevs 1036 商务旅行 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description 某首都城市的商人要经常到各城镇去做生意 ...
- CodeVs.1036 商务旅行 ( LCA 最近公共祖先 )
CodeVs.1036 商务旅行 ( LCA 最近公共祖先 ) 题意分析 某首都城市的商人要经常到各城镇去做生意,他们按自己的路线去做,目的是为了更好的节约时间. 假设有N个城镇,首都编号为1,商人从 ...
- codevs——1036 商务旅行
1036 商务旅行 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题解 查看运行结果 题目描述 Description 某首都城市的商人要经常 ...
- codevs 1036 商务旅行(Targin求LCA)
传送门 Description 某首都城市的商人要经常到各城镇去做生意,他们按自己的路线去做,目的是为了更好的节约时间. 假设有N个城镇,首都编号为1,商人从首都出发,其他各城镇之间都有道路连接,任意 ...
- CODEVS 1036 商务旅行
题目描述 Description 某首都城市的商人要经常到各城镇去做生意,他们按自己的路线去做,目的是为了更好的节约时间. 假设有N个城镇,首都编号为1,商人从首都出发,其他各城镇之间都有道路连接,任 ...
- 【最近公共祖先】【树链剖分】CODEVS 1036 商务旅行
树链剖分求lca模板.O(log(n)),就是不倍增嘛~ #include<cstdio> #include<algorithm> using namespace std; # ...
- 【最近公共祖先】【块状树】CODEVS 1036 商务旅行
在线块状树LCA模板. #include<cstdio> #include<vector> #include<algorithm> #include<cmat ...
- codevs1036商务旅行(LCA)
1036 商务旅行 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题解 题目描述 Description 某首都城市的商人要经常到各城镇去做 ...
- CODEVS——T 1036 商务旅行
http://codevs.cn/problem/1036/ 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题解 题目描述 Descript ...
随机推荐
- Python学习的一些好资料
教程: 1. 廖雪峰的Python教程:http://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a0 ...
- ibatis 环境搭建(1)
目录和jar包
- Linux——搭建PHP开发环境第四步:composer
原文链接:https://my.oschina.net/jiangbianwanghai/blog/473249 1.下载composer.phar [root#localhost opt]# cur ...
- IIC协议及其对ACK应答信号的处理
1,SCL一直由Master控制,SDA依照数据传送的方向,读数据时由Slave控制SDA,写数据时由Master控制SDA.当8位数据传送完毕之后,应答位或者否应答位的SDA控制权与数据位传送时相反 ...
- 看奢侈品Prada如何使用物联网
这是峰哥在一家国际顶级商学院听课的笔记.这是个巨变的时代,有趣的时代. 一 PRADA在纽约的旗舰店.每件衣服上都有RFID码.每当一个顾客拿起一件PRADA进试衣间,RFID会被自动识别,试衣间里的 ...
- Windows下Vundle插件BundleSearch命令出现错误解决方案
纯粹参考他人博文,已证明解决方案正确,转载时请注明参考链接!!! 参考链接: http://www.tuicool.com/articles/e2aiEn 在Windows下使用Vim时,用Vundl ...
- AlgorithmsI Exercises: Analysis of Algorithms
Question 1 Suppose that you time a program as a function of N and producethe following table. N seco ...
- GitHub的5人骨干小组:早期初创公司该如何招到正确的人
转自:http://news.cnblogs.com/n/190924/ 前 5 年对初创公司来说至关重要,根据美国中小企业发展署的数据,大约 1/4 的初创公司在第一年内关门大吉,只有不到一半的企业 ...
- Android 金融项目整理
本来是安安心心周末休假的时间,却被强征来加班.魔都今天雾霾严重,窗外都看不到360无死角都能看到的东方明珠.吃完午饭后睡一觉起来,觉得该给自己做点事情了.那就把项目里面的一些可圈可点的技术都罗列出来, ...
- 数据结构(树链剖分,堆):HNOI 2016 network
2215. [HNOI2016]网络 ★★★☆ 输入文件:network_tenderRun.in 输出文件:network_tenderRun.out 简单对比时间限制:2 s 内存 ...