HDU 2586 How far away(LCA+邻接表)
How far away
&题解:
和上篇是一样的题,这用的是lca方法做的, 不知道为什么,把数组开到80000 就a了 >_<
哈 我现在知道为什么了,因为我的rmq数组没有乘2,rmq比较的是depth数组,但是depth数组的范围是maxn*2,所以rmq的数组乘2就好了
&代码:
#include <cstdio>
#include <bitset>
#include <iostream>
#include <set>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <map>
#include <queue>
#include <vector>
using namespace std;
#define INF 0x3f3f3f3f
#define ll long long
#define fo(i,a,b) for(int i=(a);i<=(b);i++)
#define fd(i,a,b) for(int i=(a);i>=(b);i--)
const int max_v = 40000 + 7;
int rq[max_v*2][20], mm[max_v*2], n, m;
void initRMQ(int n, int b[]) {
mm[0] = -1;
for(int i = 1; i <= n; i++) {
mm[i] = (i & (i - 1)) ? mm[i - 1] : mm[i - 1] + 1;
rq[i][0] = i;
}
for(int j = 1; j <= mm[n]; j++)
for(int i = 1; i + (1 << j) - 1 <= n; i++) {
int x = rq[i][j - 1], y = rq[i + (1 << (j - 1))][j - 1];
rq[i][j] = b[x] < b[y] ? x : y;
}
}
int RMQ(int x, int y, int b[]) {
if(x > y) swap(x, y);
int k = mm[y - x + 1];
int x2 = rq[x][k], y2 = rq[y - (1 << k) + 1][k];
return b[x2] < b[y2] ? x2 : y2;
}
int dis[max_v];
struct Edge {
int u, v, w, nx;
} G[2 * max_v];
int root;
int vs[max_v * 2];
int depth[max_v * 2];
int id[max_v];
int cnt, ft[max_v * 2], vis[max_v];
void Add(int u, int v, int w) {
G[cnt].u = u; G[cnt].v = v; G[cnt].w = w;
G[cnt].nx = ft[u];
ft[u] = cnt++;
}
void dfs(int v, int p, int d, int &k) {
id[v] = k;
vs[k] = v;
depth[k++] = d;
// vis[v] = 1;
for(int i = ft[v]; ~i; i = G[i].nx) {
// printf("%d %d-- %d\n", G[i].u, G[i].v, p);
if(G[i].v != p) {
dis[G[i].v] = dis[G[i].u] + G[i].w;
dfs(G[i].v, G[i].u, d + 1, k);
vs[k] = v;
depth[k++] = d;
}
}
}
void initLCA() {
int k = 1;
memset(vis, 0, sizeof(vis));
dfs(root, -1, 0, k);
initRMQ(k - 1, depth);
}
int LCA(int u, int v) {
return vs[RMQ(min(id[u], id[v]), max(id[u], id[v]) + 1, depth)];
}
int main() {
//("E:1.in", "r", stdin);
int T; scanf("%d", &T);
while(T--) {
scanf("%d%d", &n, &m);
cnt = 0;
memset(ft, -1, sizeof(ft));
fo(i, 1, n - 1) {
int x, y, val;
scanf("%d%d%d", &x, &y, &val);
Add(x, y, val);
Add(y, x, val);
}
root = 1;
dis[root] = 0;
initLCA();
fo(i, 1, m) {
int u, v;
scanf("%d%d", &u, &v);
printf("%d\n", dis[u] + dis[v] - 2 * dis[LCA(u, v)]);
}
}
return 0;
}
这个是用临街矩阵写的,RT了,但有注释
#include <cstdio>
#include <bitset>
#include <iostream>
#include <set>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <map>
#include <queue>
#include <vector>
using namespace std;
#define INF 0x3f3f3f3f
#define ll long long
#define fo(i,a,b) for(int i=(a);i<=(b);i++)
#define fd(i,a,b) for(int i=(a);i>=(b);i--)
#define pii pair<int,int>
//RMQ 相关
const int maxn = 40000 + 7, max_v = maxn;
int dp[maxn][20], mm[maxn], n, m;
void initRMQ(int n, int b[]) {
mm[0] = -1;
for(int i = 1; i <= n; i++) {
mm[i] = (i & (i - 1)) ? mm[i - 1] : mm[i - 1] + 1;
dp[i][0] = i;
}
for(int j = 1; j <= mm[n]; j++)
for(int i = 1; i + (1 << j) - 1 <= n; i++) {
int x = dp[i][j - 1], y = dp[i + (1 << (j - 1))][j - 1];
dp[i][j] = b[x] < b[y] ? x : y;
// dp[i][j] = min(dp[i][j - 1], dp[i + (1 << (j - 1))][j - 1]);
}
}
int RMQ(int x, int y, int b[]) {
if(x > y) swap(x, y);
int k = mm[y - x + 1];
int x2 = dp[x][k], y2 = dp[y - (1 << k) + 1][k];
return b[x2] < b[y2] ? x2 : y2;
}
int dis[maxn];
//LCA 相关
vector<pii> G[max_v]; //图的邻接表
int root;
int vs[max_v * 2]; //dfs访问的顺序
int depth[max_v * 2]; //节点深度
int id[max_v]; //各顶点在vs中首次出现的下标
//v:现节点 p:父节点 d:深度 k:编号
void dfs(int v, int p, int d, int &k) {
id[v] = k;
vs[k] = v;
depth[k++] = d;
for(int i = 0; i < G[v].size(); i++) {
if(G[v][i].first != p) {
dis[G[v][i].first] = dis[v] + G[v][i].second;
dfs(G[v][i].first, v, d + 1, k);
vs[k] = v;
depth[k++] = d;
}
}
}
void initLCA(int V) {
int k = 1;
dfs(root, -1, 0, k);
initRMQ(k - 1, depth);
}
int LCA(int u, int v) {
return vs[RMQ(min(id[u], id[v]), max(id[u], id[v]) + 1, depth)];
}
int main() {
//("E:1.in", "r", stdin);
int T; scanf("%d", &T);
while(T--) {
scanf("%d%d", &n, &m);
fo(i, 1, n) G[i].clear();
fo(i, 1, n - 1) {
int x, y, val;
scanf("%d%d%d", &x, &y, &val);
G[x].push_back(make_pair(y, val));
G[y].push_back(make_pair(x, val));
}
root = 1;
dis[root] = 0;
initLCA(n);
fo(i, 1, m) {
int u, v;
scanf("%d%d", &u, &v);
printf("%d\n", dis[u] + dis[v] - 2 * dis[LCA(u, v)]);
}
// for(int i = 0; i < 8; i++) {
// printf("%3d", i);
// } printf("\n");
// for(int i = 0; i < 8; i++) {
// printf("%3d", dis[i]);
// } printf("\n");
}
return 0;
}
HDU 2586 How far away(LCA+邻接表)的更多相关文章
- HDU 2586 How far away(dfs+邻接表)
How far away [题目链接]How far away [题目类型]dfs+邻接表 &题意: 题目大意:一个村子里有n个房子,这n个房子用n-1条路连接起来,接下了有m次询问,每次询问 ...
- hdu 2586(最近公共祖先LCA)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2586 思路:在求解最近公共祖先的问题上,用到的是Tarjan的思想,从根结点开始形成一棵深搜树,非常好 ...
- HDU 2586 How far away? LCA 转化成RMQ
链接:http://acm.hdu.edu.cn/showproblem.php?pid=2586 [题意] 给出一个N 个和N-1条边的连通图,询问任意两点间的距离.N<=40000 . [分 ...
- HDU 2586 倍增法求lca
How far away ? Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)To ...
- TTTTTTTTTTTTTTTTT HDU 2586 How far away LCA的离线算法 Tarjan
链接: How far away ? Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Other ...
- 【HDU 2586 How far away?】LCA问题 Tarjan算法
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2586 题意:给出一棵n个节点的无根树,每条边有各自的权值.给出m个查询,对于每条查询返回节点u到v的最 ...
- HDU 2586 How far away ?【LCA】
任意门:http://acm.hdu.edu.cn/showproblem.php?pid=2586 How far away ? Time Limit: 2000/1000 MS (Java/Oth ...
- LCA(最近公共祖先)--tarjan离线算法 hdu 2586
HDU 2586 How far away ? Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/ ...
- HDU 4858 项目管理(邻接表 暴力模拟)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4858 我们建造了一个大项目!这个项目有n个节点,用很多边连接起来,并且这个项目是连通的! 两个节点间可 ...
随机推荐
- oracle sql 获取本季度所有月份,上季度所有月份
上季度所有月份: ),-ROWNUM),'YYYYMM') LAST_Q A FROM DUAL) CONNECT ; 本季度所有月份: ),-ROWNUM),'YYYYMM') LAST_Q FRO ...
- 框架源码系列七:Spring源码学习之BeanDefinition源码学习(BeanDefinition、Annotation 方式配置的BeanDefinition的解析)
一.BeanDefinition 1. bean定义都定义了什么? 2.BeanDefinition的继承体系 父类: AttributeAccessor: 可以在xml的bean定义里面加上DTD ...
- spring 测试类test测试方法
实例掩码地址为:孔浩组织结构设计 web.xml配置文件: <!-- Spring 的监听器可以通过这个上下文参数来获取beans.xml的位置 --> <context-param ...
- 使用DDL触发器同步多个数据库结构
使用DDL触发器同步多个数据库结构 背景:当开发组比较大时,势必会分布到不同的地理位置,若无法在同一个快速网络中工作,就会造成多个开发库并存的局面,这样就需要多个开发库结构的同步,甚至是开发测试数据的 ...
- Sqlalchemy model 文件自动生成
自动生成Sqlalchemy的models文件的包早用过了,有个字段类型做了改动,调了得10几分钟才搞定.记录下自动生成models文件的python包sqlacodegen sqlacodegen已 ...
- java Illegal unquoted character ((CTRL-CHAR, code X)): has to be escaped using backslash to be included in string value
今天在同步日志到ES的时候出现转换Json后 存到es中报这个错. Illegal unquoted character ((CTRL-CHAR, code X)): has to be escape ...
- C# 鼠标移动Winform窗体内或者panel容器内的控件 显示虚线/实现虚线框来确定位置
C# 鼠标移动WinForm窗体或者panel容器内的控件 移动虚线/实现虚线框来确定位置 1.用到的方法介绍 今天,根据领导指示指导移动容器内的控件,生成虚线框,使用 ControlPaint.Dr ...
- jquery实现同时展示多个tab标签+左右箭头实现来回滚动(美化版增加删除按钮)
闲聊 前段时间小颖分享了:jquery实现同时展示多个tab标签+左右箭头实现来回滚动文章,引入项目后,我们的组长说样子太丑了,小颖觉得还好啊,要不大家评评理,看下丑不丑?无图无真相,来上图: 看吧其 ...
- C# Aspose.Cells导出xlsx格式Excel,打开文件报“Excel 已完成文件级验证和修复。此工作簿的某些部分可能已被修复或丢弃”
报错信息: 最近打开下载的 Excel,会报如下错误.(xls 格式不受影响) 解决方案: 下载代码(红色为新添代码) public void download() { string fileName ...
- RE:从零开始的莫比乌斯反演
炫酷反演魔术根本看不懂啊...也就看看PoPoQQQ的ppt了. 这个赛季结束了,一年可以学很多很多东西呢. 因为我是写给自己看的所以写的很垃圾. 公式: 按我的理解,反演就是 x可以表示成y,然后 ...