传送门

解题思路

货车所走的路径一定是最大生成树上的路径,所以先跑一个最大生成树,之后就是求一条路径上的最小值,用树剖+线段树,注意图可能不连通。将边权下放到点权上,但x,y路径上的lca的答案不能算,因为他的点权来自上面的路径。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm> using namespace std;
const int MAXN = ;
const int inf = 0x3f3f3f3f; inline int rd(){
int x=,f=;char ch=getchar();
while(!isdigit(ch)) {f=ch=='-'?:;ch=getchar();}
while(isdigit(ch)) {x=(x<<)+(x<<)+ch-'';ch=getchar();}
return f?x:-x;
} int n,m,head[MAXN],cnt,to[MAXN<<],nxt[MAXN<<],w[MAXN],Fa[MAXN],val[MAXN<<];
int fa[MAXN],dep[MAXN],id[MAXN],wt[MAXN],top[MAXN],siz[MAXN],son[MAXN];
int Min[MAXN<<],num,q;
bool vis[MAXN]; struct Node{
int u,v,z;
}node[MAXN]; inline bool cmp(Node A,Node B){
return A.z>B.z;
} int get(int x){
if(x==Fa[x]) return x;
return Fa[x]=get(Fa[x]);
} inline void add(int bg,int ed,int ww){
to[++cnt]=ed,nxt[cnt]=head[bg],val[cnt]=ww,head[bg]=cnt;
} void dfs1(int x,int f,int d){
fa[x]=f,dep[x]=d,siz[x]=,vis[x]=;
int maxson=-,u;
for(register int i=head[x];i;i=nxt[i]){
u=to[i];if(u==f) continue;
w[u]=val[i];dfs1(u,x,d+);
siz[x]+=siz[u];
if(siz[u]>maxson) {maxson=siz[u];son[x]=u;}
}
} void dfs2(int x,int topf){
id[x]=++num;wt[num]=w[x];top[x]=topf;
if(!son[x]) return;
dfs2(son[x],topf);int u;
for(register int i=head[x];i;i=nxt[i]){
u=to[i];if(u==fa[x] || u==son[x]) continue;
dfs2(u,u);
}
} void build(int x,int l,int r){
if(l==r) {
Min[x]=wt[l];
return;
}
int mid=(l+r)>>;
build(x<<,l,mid),build(x<<|,mid+,r);
Min[x]=min(Min[x<<],Min[x<<|]);
} int query(int x,int l,int r,int L,int R){
if(L<=l && r<=R) return Min[x];
int mid=l+r>>,ret=inf;
if(L<=mid) ret=min(ret,query(x<<,l,mid,L,R));
if(mid<R) ret=min(ret,query(x<<|,mid+,r,L,R));
return ret;
} int qRange(int x,int y){
int u=get(x),v=get(y),ret=inf;
if(u!=v) return -;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
ret=min(ret,query(,,n,id[top[x]],id[x]));
x=fa[top[x]];
}
if(x==y) return ret;
if(dep[x]>dep[y]) swap(x,y);
ret=min(ret,query(,,n,id[x]+,id[y]));
return ret;
} int main(){
n=rd(),m=rd();int x,y;
for(int i=;i<=n;i++) Fa[i]=i;
for(int i=;i<=m;i++) node[i].u=rd(),node[i].v=rd(),node[i].z=rd();
sort(node+,node++m,cmp);int uu,vv;
for(int i=;i<=m;i++){
uu=get(node[i].u),vv=get(node[i].v);
if(uu!=vv) {
Fa[uu]=vv;
add(node[i].u,node[i].v,node[i].z);
add(node[i].v,node[i].u,node[i].z);
}
}
for(int i=;i<=n;i++)
if(!vis[i]) {w[i]=inf;dfs1(i,,);dfs2(i,i);}
q=rd();build(,,n);
while(q--){
x=rd(),y=rd();
printf("%d\n",qRange(x,y));
}
return ;
}

LUOGU P1967 货车运输(最大生成树+树剖+线段树)的更多相关文章

  1. BZOJ_2238_Mst_树剖+线段树

    BZOJ_2238_Mst_树剖+线段树 Description 给出一个N个点M条边的无向带权图,以及Q个询问,每次询问在图中删掉一条边后图的最小生成树.(各询问间独立,每次询问不对之后的询问产生影 ...

  2. BZOJ_4551_[Tjoi2016&Heoi2016]树_树剖+线段树

    BZOJ_4551_[Tjoi2016&Heoi2016]树_树剖+线段树 Description 在2016年,佳媛姐姐刚刚学习了树,非常开心.现在他想解决这样一个问题:给定一颗有根树(根为 ...

  3. BZOJ_2157_旅游_树剖+线段树

    BZOJ_2157_旅游_树剖+线段树 Description Ray 乐忠于旅游,这次他来到了T 城.T 城是一个水上城市,一共有 N 个景点,有些景点之间会用一座桥连接.为了方便游客到达每个景点但 ...

  4. 【BZOJ5210】最大连通子块和 树剖线段树+动态DP

    [BZOJ5210]最大连通子块和 Description 给出一棵n个点.以1为根的有根树,点有点权.要求支持如下两种操作: M x y:将点x的点权改为y: Q x:求以x为根的子树的最大连通子块 ...

  5. [LNOI2014]LCA(树剖+线段树)

    \(\%\%\% Fading\) 此题是他第一道黑题(我的第一道黑题是蒲公英) 一直不敢开,后来发现是差分一下,将询问离线,树剖+线段树维护即可 \(Code\ Below:\) #include ...

  6. [CF1007D]Ants[2-SAT+树剖+线段树优化建图]

    题意 我们用路径 \((u, v)\) 表示一棵树上从结点 \(u\) 到结点 \(v\) 的最短路径. 给定一棵由 \(n\) 个结点构成的树.你需要用 \(m\) 种不同的颜色为这棵树的树边染色, ...

  7. LOJ#3088. 「GXOI / GZOI2019」旧词(树剖+线段树)

    题面 传送门 题解 先考虑\(k=1\)的情况,我们可以离线处理,从小到大对于每一个\(i\),令\(1\)到\(i\)的路径上每个节点权值增加\(1\),然后对于所有\(x=i\)的询问查一下\(y ...

  8. BZOJ3531-[Sdoi2014]旅行(树剖+线段树动态开点)

    传送门 完了今天才知道原来线段树的动态开点和主席树是不一样的啊 我们先考虑没有宗教信仰的限制,那么就是一个很明显的树剖+线段树,路径查询最大值以及路径和 然后有了宗教信仰的限制该怎么做呢? 先考虑暴力 ...

  9. 【bzoj4699】树上的最短路(树剖+线段树优化建图)

    题意 给你一棵 $n$ 个点 $n-1$ 条边的树,每条边有一个通过时间.此外有 $m$ 个传送条件 $(x_1,y_1,x_2,y_2,c)$,表示从 $x_1$ 到 $x_2$ 的简单路径上的点可 ...

随机推荐

  1. 3. Vim入门教程

    1. 基本概念 1.1 了解Vim的三个基本模式 当我们安装完一个编辑器后,肯定会打开它,然后在里面输入点什么东西,但是打你打开Vim后,想要输入点什么却发现自己什么都没有输入,所以在写点东西之前,先 ...

  2. bagging和boosting以及rand-forest

    bagging: 让该学习算法训练多轮,每轮的训练集由从初始的训练集中随机取出的n个训练样本组成,某个初始训练样本在某轮训练集中可以出现多次或根本不出现,训练之后可得到一个预测函数序列h_1,⋯ ⋯h ...

  3. Day 10:函数全局变量和局部变量及函数嵌套

    全局变量:在所有函数之外赋值的变量,是全局变量. 局部变量:在函数内的变量是,局部变量 一个函数被调用时,就创建了一个局部作用域.在这个函数内赋值的所有变量,存在于该局部作用域内.该函数返回时,这个局 ...

  4. ## jvm知识点零碎整理

    1.初始化VM options配置 idea安装目录\bin\idea.exe.vmoptions 和 idea64.exe.vmoptions可以看到初始配置: -Xms128m  (设置初始化堆内 ...

  5. canvas填充规则,非零环绕

    1.看一块区域是否填充 2.从这个区域拉一条直线 3,看和这条直线相交的轨迹 4.如果顺时针轨迹+1 5.如果逆时针轨迹-1 6.所有轨迹的值计算出来 7.如果是非0,那么填充 8.如果是0那么不填充

  6. js 阻止事件

    event.stopPropagation();//阻止事件冒泡 ,可阻止父类事件的发生 event.preventDefault();//阻止默认行为 如A标签

  7. CSIC_716_20191126【面向对象编程--继承】

    继承 什么是继承:继承是新建类的一种方式,通过此方式生成的类称为子类.或者 派生类,被继承的类称为父类.基类或超类.在python中,一个子类可以继承多个父类. 继承的作用:减少代码的冗余,提高开发效 ...

  8. Java怎样实现解析身份证号

    身份证号解析,demo /** * 身份证号解析demo * */ public class TestArea { public static void main(String[] args) { S ...

  9. webstorm安装与破解

    1.下载webstorm和补丁文件 链接:https://pan.baidu.com/s/1aiHxPExAbDCcHxKtB82_vg 提取码:jo07 链接:https://pan.baidu.c ...

  10. CodeForces - 803F

    http://codeforces.com/problemset/problem/803/F #include <iostream> #include <cstdio> #in ...