题目链接:https://www.luogu.org/problemnew/show/P2245

= 货车运输

被逼着写过mst+lca

后来成了mst+树剖

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 100010;
int n, m, q, node[maxn], f[maxn];
struct mst{
int u, v, w;
}ee[maxn*3];
struct edge{
int next, to, len;
}e[maxn*3];
int head[maxn], cnt;
void add(int u, int v, int w)
{
e[++cnt].len = w; e[cnt].next = head[u]; e[cnt].to = v; head[u] = cnt;
e[++cnt].len = w; e[cnt].next = head[v]; e[cnt].to = u; head[v] = cnt;
}
//-----Kruskal-----
bool cmp(mst a, mst b)
{
return a.w > b.w;
}
int find(int x)
{
return f[x] == x ? x : f[x] = find(f[x]);
}
void Kruskal()
{
sort(ee+1, ee+1+m, cmp);
for(int i = 1; i <= m; i++)
{
if(find(ee[i].u) == find(ee[i].v)) continue;
add(ee[i].v, ee[i].u, ee[i].w);
f[find(ee[i].v)] = f[find(ee[i].u)];
}
}
//----------------
int top[maxn], size[maxn], son[maxn], fa[maxn], seg[maxn], rev[maxn], deep[maxn], num = -1;
void dfs(int u, int f)
{
fa[u] = f;
for(int i = head[u]; i != -1; i = e[i].next)
{
if(e[i].to == fa[u]) continue;
node[e[i].to] = e[i].len;
dfs(e[i].to, u);
}
}
void dfs1(int u)
{
int maxson = -1;
deep[u] = deep[fa[u]]+1;
size[u] = 1;
son[u] = n+1;
for(int i = head[u]; i != -1; i = e[i].next)
{
int v = e[i].to;
if(v == fa[u]) continue;
dfs1(v);
size[u] += size[v];
if(maxson < size[v]) maxson = size[v], son[u] = v;
}
}
void dfs2(int u, int t)
{
top[u] = t;
num++;
seg[u] = num;
rev[num] = u;
if(son[u] != n+1) dfs2(son[u], t);
for(int i = head[u]; i != -1; i = e[i].next)
{
if(e[i].to == fa[u] || e[i].to == son[u]) continue;
dfs2(e[i].to, e[i].to);
}
}
//-------------------
class Segment_Tree{
#define lson l, mid, rt<<1
#define rson mid+1, r, rt<<1|1
public:
int tree[maxn<<2];
void build(int l, int r, int rt)
{
if(l == r)
{
tree[rt] = node[rev[l]];
return;
}
int mid = (l + r) >> 1;
build(lson);
build(rson);
PushUP(rt);
}
int query(int left, int right, int l, int r, int rt)
{
int res = 0x7fffffff;
if(left <= l && r <= right) return tree[rt];
int mid = (l + r) >> 1;
if(left <= mid) res = min(res, query(left, right, lson));
if(right > mid) res = min(res, query(left, right, rson));
return res;
}
int Qrange(int x, int y)
{
int ret = 0x7fffffff;
while(top[x] != top[y])
{
if(deep[top[x]] < deep[top[y]]) swap(x, y);
ret = min(ret, query(seg[top[x]], seg[x], 1, n, 1));
x = fa[top[x]];
}
if(deep[x] > deep[y]) swap(x, y);
ret = min(ret, query(seg[x]+1, seg[y], 1, n, 1));
return ret;
}
private:
void PushUP(int rt)
{
tree[rt] = min(tree[rt<<1], tree[rt<<1|1]);
}
}T;
int main()
{
ios::sync_with_stdio(false);
memset(head, -1, sizeof(head));
cin>>n>>m;
for(int i = 1; i <= m; i++) cin>>ee[i].u>>ee[i].v>>ee[i].w;
for(int i = 1; i <= n; i++) f[i] = i;
Kruskal();
memset(fa, -1, sizeof(fa));
fa[0] = 0;
for(int i = 1; i <= n; i++) if(fa[i] == -1) dfs(i, 0);
for(int i = 1; i <= n; i++) if(fa[i] == 0) add(i, 0, 0);
dfs1(0);
dfs2(0, 0);
T.build(1, n, 1);
cin>>q;
for(int i = 1; i <= q; i++)
{
int x, y;
cin>>x>>y;
if(find(x) != find(y)) cout<<"-1\n";
else cout<<T.Qrange(x, y)<<"\n";
}
return 0;
}

【luogu P2245 星际导航】 题解的更多相关文章

  1. [LUOGU] P2245 星际导航

    题目描述 sideman做好了回到Gliese 星球的硬件准备,但是sideman的导航系统还没有完全设计好.为了方便起见,我们可以认为宇宙是一张有N 个顶点和M 条边的带权无向图,顶点表示各个星系, ...

  2. Luogu 2245 星际导航(最小生成树,最近公共祖先LCA,并查集)

    Luogu 2245 星际导航(最小生成树,最近公共祖先LCA,并查集) Description sideman做好了回到Gliese 星球的硬件准备,但是sideman的导航系统还没有完全设计好.为 ...

  3. 洛谷 P2245 星际导航 解题报告

    P2245 星际导航 题目描述 sideman做好了回到Gliese 星球的硬件准备,但是sideman的导航系统还没有完全设计好.为了方便起见,我们可以认为宇宙是一张有N 个顶点和M 条边的带权无向 ...

  4. P2245 星际导航 瓶颈路

    \(\color{#0066ff}{ 题目描述 }\) sideman 做好了回到 \(\text{Gliese}\) 星球的硬件准备,但是 \(\text{sideman}\) 的导航系统还没有完全 ...

  5. P2245 星际导航

    题目描述 sideman 做好了回到 Gliese星球的硬件准备,但是 sideman 的导航系统还没有完全设计好.为了方便起见,我们可以认为宇宙是一张有 N 个顶点和 M 条边的带权无向图,顶点表示 ...

  6. [洛谷P2245]星际导航

    题目大意:有一张n点m边的带权无向图,和一些问题,每次询问两个点之间的路径的最大边权最小是多少. 解题思路:同NOIP2013货车运输,只是数据增大,大变成小,小变成大了而已.所以具体思路见货车运输. ...

  7. 最小生成树+LCA【洛谷 P2245】 星际导航

    [洛谷 P2245] 星际导航 题目描述 sideman做好了回到Gliese 星球的硬件准备,但是sideman的导航系统还没有完全设计好.为了方便起见,我们可以认为宇宙是一张有N 个顶点和M 条边 ...

  8. Luogu P2754 星际转移问题

    Luogu P2754 星际转移问题 思路 首先,对于地球能否到达月球的问题,考虑使用并查集维护. 对于每艘飞船能够到达的站点,放进一个集合里,若两艘飞船的集合有交集,那么就合并两个集合,最后只要地球 ...

  9. 【洛谷P2245】星际导航

    题面 题解 \(kruskal\)重构树板子题??(大雾 因为重构树上两点之间的\(LCA\)的权值就是原图上最小生成树上的瓶颈. 所以建个重构树,跑\(LCA\)即可. 代码 #include< ...

随机推荐

  1. java设计模式-----4、单例模式

    单例模式是一种对象创建型模式,使用单例模式,可以保证为一个类只生成唯一的一个实例对象.也就是说,在整个程序空间中,该类只存在一个实例对象. 其实,GoF对单例模式的定义是:保证一个类,只有一个实例存在 ...

  2. python中类变量和实例变量

    1. 类变量和实例变量 在Python Tutorial中对于类变量和实例变量是这样描述的: Generally speaking, instance variables are for data u ...

  3. let 和 var 区别

    javascript 严格模式 第一次接触let关键字,有一个要非常非常要注意的概念就是”javascript 严格模式”,比如下述的代码运行就会报错: <Javascript 严格模式详解&g ...

  4. 解决ArcMap启动时只停留在初始化界面的方法

    方法1 修改环境变量TEMP和TMP为C:\Temp 重启ArcMap. 方法2 关闭系统进程Print Spooler. 打开C:\WINDOWS\system32\spool\PRINTERS,删 ...

  5. Vue打包桌面程序

    开源的地址:https://github.com/electron/electron-quick-start 一.运行 1. 安装依赖 cnpm install electron --save cnp ...

  6. Arcgis GDB文件地理数据库、shapefile、coverage 和其他基于文件的数据源所支持的函数的完整列表

    函数 以下是文件地理数据库.shapefile.coverage 和其他基于文件的数据源所支持的函数的完整列表.个人地理数据库和 ArcSDE 地理数据库也支持这些函数,但这些数据源可能使用不同的语法 ...

  7. Android Weekly Notes Issue #247

    Android Weekly Issue #247 March 5th, 2017 Android Weekly Issue #247. 本期内容包括: 离线模式的实现; RxJava2的测试支持; ...

  8. js 正则常用函数

    正则表达式中,需要转义的字符: * . ? + $ ^ [ ] ( ) { } | \ / let reg = /\d+/g let str = 'ad/23/dfww/454/6' 1. reg.t ...

  9. Android数据统计

    开发效率可以用这些方式提升: 1 . 构建公用工具类,方便大家使用 2 . 使用开源的一些包,例如ORM思想的数据库等 3 . 可以很快的找到问题.开发中,找bug的时间,往往是很多的.我用的方法有3 ...

  10. SQL 语句及关键字的用法

    一.SELECT select [ALL|DISTINCT] select_list [into new table] FROM table_source [where serch_conditaio ...