poj 1986LCA离线dfs+并查集
题意,给出边和权值,求出两个点间的最短距离。
用离线算法的时候有个地方不知道怎么处理了。在线的本来想用倍增的,但发现倍增算法貌似需要预处理深度而不是权值,不知道怎么处理。套一个rmq的模板吧,用来处理权值的时候。
代码:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>
using namespace std; const int NN=100010; int n,m;
vector<pair<int,int> > edge[NN],qe[NN];
vector<int> q1,q2; int p[NN];
int find(int x)
{
if (p[x]!=x) p[x]=find(p[x]);
return p[x];
} int sum=0,ans[NN],dis[NN];
bool vis[NN]={0};
void lca(int u,int fa)
{
p[u]=u;
for (int i=0; i<edge[u].size(); i++)
{
int v=edge[u][i].first;
if (v==fa) continue;
dis[v]=dis[u]+edge[u][i].second;
lca(v,u);
p[v]=u;
}
vis[u]=true;
if (sum==m) return;
for (int i=0; i<qe[u].size(); i++)
{
int v=qe[u][i].first;
if (vis[v])
ans[qe[u][i].second]=dis[u]+dis[v]-2*dis[find(v)];
}
} int main()
{
int u,v,w;
char str[4];
scanf("%d%d",&n,&m);
for (int i=1; i<=n; i++)
{
edge[i].clear();
}
for (int i=1; i<=m; i++)
{
scanf("%d%d%d%s",&u,&v,&w,str);
edge[u].push_back(make_pair(v,w));
edge[v].push_back(make_pair(u,w));
}
scanf("%d",&m);
for (int i=0; i<m; i++)
{
scanf("%d%d",&u,&v);
qe[u].push_back(make_pair(v,i));
qe[v].push_back(make_pair(u,i));
ans[i]=0;
}
dis[1]=0;
lca(1,0);
for (int i=0; i<m; i++) printf("%d\n",ans[i]);
return 0;
}
在线的dfs+rmq模板套一个:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath>
#include <vector>
using namespace std; const int NN=50000; int n,rt;
vector<pair<int,int> > edge[NN]; int depth=0;
int bn=0,b[NN*2]; //深度序列
int f[NN*2]; //对应深度序列中的结点编号
int p[NN]; //结点在深度序列中的首位置
int dis[NN]; //结点到根的距离
void dfs(int u,int fa)
{
int tmp=++depth;
b[++bn]=tmp; f[tmp]=u; p[u]=bn;
for (int i=0; i<edge[u].size(); i++)
{
int v=edge[u][i].first;
if (v==fa) continue;
dis[v]=dis[u]+edge[u][i].second;
dfs(v,u);
b[++bn]=tmp;
}
} int dp[NN*2][20];
void rmq_init(int n) //以深度序列做rmq
{
for (int i=1; i<=n; i++) dp[i][0]=b[i];
int m=floor(log(n*1.0)/log(2.0));
for (int j=1; j<=m; j++)
for (int i=1; i<=n-(1<<j)+1; i++)
dp[i][j]=min(dp[i][j-1],dp[i+(1<<(j-1))][j-1]);
}
int rmq(int l,int r)
{
int k=floor(log((r-l+1)*1.0)/log(2.0));
return min(dp[l][k],dp[r-(1<<k)+1][k]);
} int lca(int a,int b)
{
if (p[a]>p[b]) swap(a,b);
int k=rmq(p[a],p[b]);
return f[k];
} int main()
{
int m,u,v,w;
char str[4];
scanf("%d%d",&n,&m);
for (int i=1; i<=n; i++) edge[i].clear();
while (m--)
{
scanf("%d%d%d%s",&u,&v,&w,str);
edge[u].push_back(make_pair(v,w));
edge[v].push_back(make_pair(u,w));
}
rt=1; dis[rt]=0;
dfs(1,0);
rmq_init(bn);
scanf("%d",&m);
while (m--)
{
scanf("%d%d",&u,&v);
printf("%d\n",dis[u]+dis[v]-2*dis[lca(u,v)]);
}
return 0;
}
poj 1986LCA离线dfs+并查集的更多相关文章
- 【bzoj5183】[Baltic2016]Park 离线+对偶图+并查集
题目描述 在Byteland的首都,有一个矩形围栏围起来的公园.在这个公园里树和访客都以一个圆形表示.公园有四个出入口,每个角落一个(1=左下角,2=右下角,3=右上角,4=左上角).访客能通过这些出 ...
- POJ 1562 Oil Deposits (并查集 OR DFS求联通块)
Oil Deposits Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 14628 Accepted: 7972 Des ...
- 距离LCA离线算法Tarjan + dfs + 并查集
距离B - Distance in the Tree 还是普通的LCA但是要求的是两个节点之间的距离,学到了一些 一开始我想用带权并查集进行优化,但是LCA合并的过程晚于离线计算的过程,所以路径长度会 ...
- HDU 5441 离线处理 + 并查集
题意:给n个节点m条带权值边的无向图.然后q个问题,每次询问点对的数目,点对需要满足的条件是:1)连通:2)其路径的最大权值不能超过询问值. 分析:如果没次询问一次,dfs一次,很可能超时,因此可以用 ...
- poj 1733(带权并查集+离散化)
题目链接:http://poj.org/problem?id=1733 思路:这题一看就想到要用并查集做了,不过一看数据这么大,感觉有点棘手,其实,我们仔细一想可以发现,我们需要记录的是出现过的节点到 ...
- poj 1182 食物链 (并查集)
http://poj.org/problem?id=1182 关于并查集 很好的一道题,开始也看了一直没懂.这次是因为<挑战程序设计竞赛>书上有讲解看了几遍终于懂了.是一种很好的思路,跟网 ...
- POJ 1182 食物链(并查集拆点)
[题目链接] http://poj.org/problem?id=1182 [题目大意] 草原上有三种物种,分别为A,B,C A吃B,B吃C,C吃A. 1 x y表示x和y是同类,2 x y表示x吃y ...
- 分珠(dfs+并查集)
1140 分珠 时间限制:500MS 内存限制:65536K提交次数:24 通过次数:18 题型: 编程题 语言: G++;GCC Description 如下图所示,有若干珠子,每颗珠子重量不 ...
- Codeforces 1027D Mouse Hunt (强连通缩点 || DFS+并查集)
<题目链接> 题目大意: 有n个房间,每个房间都会有一只老鼠.处于第i个房间的老鼠可以逃窜到第ai个房间中.现在要清理掉所有的老鼠,而在第i个房间中防止老鼠夹的花费是ci,问你消灭掉所有老 ...
随机推荐
- Uva140 Bandwidth 全排列+生成测试法+剪枝
参考过仰望高端玩家的小清新的代码... 思路:1.按字典序对输入的字符串抽取字符,id[字母]=编号,id[编号]=字母,形成双射 2.邻接表用两个vector存储,存储相邻关系 ...
- 测试与开发如何有效沟通,QC11(HP ALM 11)的简单使用记录
笔者所在的项目组使用的缺陷管理工具是HP的QC11,作为测试人员,为了与开发一起跟随Bug的一生,简单的写了使用流程,这里记录一下,主要是让开发人员熟悉一下. 首先使用账户登录QC,如地址: http ...
- 让这三个月来的更猛烈些吧,前端react同构项目
昨天一篇文章讲述了我在这三个月中由.net到java的过程,其中踩坑填坑的细节真不是三言两语可以道尽,而完成时的喜悦也远非寻常可比(仅次于涨工资).然而到这并不算完结,作为前后端分离的忠实粉丝,我认为 ...
- 開源sources
學了c++已經快有半年光景,感覺在停留在syntax上已經不能感到有所滿足.一下是一些開源資料,難度極高,姑且當作是個人的一個小小wishing list,當作to-do list 般去執行吧. ht ...
- JavaScript中的EcMAScript学习笔记
一.Javascript概述(知道) a.一种基于对象和事件驱动的脚本语言 b.作用: 给页面添加动态效果 c.历史: 原名叫做livescript.W3c组织开发的标准叫ECMAs ...
- java 内存模型的理解
之前一直在实习,博客停写了一段时间,现在秋招开始了,所以辞职回来专心看书,同时将每天的收获以博客的形式记录下来.最近在看jvm相关的书籍,下面对面试中问得最多的部分--java 内存模型. 本篇博客大 ...
- 填涂颜色 洛谷 p1162
题目描述 由数字0 组成的方阵中,有一任意形状闭合圈,闭合圈由数字1构成,围圈时只走上下左右4个方向.现要求把闭合圈内的所有空间都填写成2.例如:6X6的方阵(n=6),涂色前和涂色后的方阵如下: 0 ...
- HDU 1176 免费馅饼:dp
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1176 题意: 横坐标范围为[0,10],你在第0秒站在坐标为5的地方. 在接下来的一段时间内,会有n个 ...
- easyui+ztree 后台管理系统模板
用easyui+ztree做了个后台管理系统模板,效果图: 下载地址: csdn:http://download.csdn.net/detail/jackpay/6744505 github:http ...
- .Net Framework下对Dapper二次封装迁移到.Net Core2.0遇到的问题以及对Dapper的封装介绍
今天成功把.Net Framework下使用Dapper进行封装的ORM成功迁移到.Net Core 2.0上,在迁移的过程中也遇到一些很有意思的问题,值得和大家分享一下.下面我会还原迁移的每一个过程 ...