luogu题解P1967货车运输--树链剖分
题目链接
https://www.luogu.org/problemnew/show/P1967
分析
NOIp的一道裸题,直接在最大生成树上剖分取最小值一下就完事了,非常好写,常数也比较小,然而题解里有许多我没见过的船新操作,先挖个坑等有时间再看
注意
树链剖分又在第一遍挂了,忘了写top[now]=t;
注意题目说明并没有保证是联通的!!!然后成功被Hack了.这真的要警惕,指不定哪天毒瘤出题人就在这里把你正解卡成60(flag++)
代码
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cctype>
#include <vector>
#include <queue>
#define ll long ong
#define ri register int
#define ull unsigned long long
using std::vector;
using std::swap;
using std::min;
using std::max;
using std::sort;
template <class T>inline void read(T &x){
x=0;int ne=0;char c;
while(!isdigit(c=getchar()))ne=c=='-';
x=c-48;
while(isdigit(c=getchar()))x=(x<<3)+(x<<1)+c-48;
x=ne?-x:x;return ;
}
const int maxn=10005;
const int maxm=50005;
const int inf=0x7fffffff;
int n,m;
struct Edge{
int x,y,c;
Edge(int _x,int _y,int _c){x=_x,y=_y,c=_c;}
Edge(){x=y=c=0;}
bool operator <(const Edge &b)const {
return c>b.c;
}
}edge[maxm];
struct Dat{
int ver,dis;
Dat(int x,int y){ver=x,dis=y;}
Dat(){;}
};
vector<Dat>g[maxn];
int pa[maxn];
int get(int x){
if(pa[x]!=x)pa[x]=get(pa[x]);//return pa[x]==x?pa[x]:pa[x]=get(pa[x]);
return pa[x];
}
inline void kruskal(){
int cnt=0,x,y,xx,yy,c;
sort(edge+1,edge+1+m);
for(ri i=1;i<=n;i++)pa[i]=i;
for(ri i=1;i<=m;i++){
//printf("%d\n",edge[i].c);
int x=edge[i].x,y=edge[i].y;
xx=get(x),yy=get(y);
if(xx==yy)continue;
c=edge[i].c;
//printf("%d %d %d\n",x,y,c);
g[x].push_back(Dat(y,c));
g[y].push_back(Dat(x,c));
pa[xx]=yy;
cnt++;
if(cnt==n-1)break;
}
return ;
}
int dep[maxn],son[maxn],top[maxn],size[maxn],dfn[maxn],fa[maxn],rnk[maxn],tot=0;
int w[maxn];
void dfs_1(int now){
int v;size[now]=1;
for(ri i=0;i<g[now].size();i++){
v=g[now][i].ver;
if(v==fa[now])continue;
fa[v]=now,dep[v]=dep[now]+1;
w[v]=g[now][i].dis;
dfs_1(v);
size[now]+=size[v];
if(!son[now]||size[v]>size[son[now]])son[now]=v;
}
return ;
}
void dfs_2(int now,int t){
int v;dfn[now]=++tot,rnk[tot]=now,top[now]=t;
if(!son[now])return ;
dfs_2(son[now],t);
for(ri i=0;i<g[now].size();i++){
v=g[now][i].ver;
if(v==fa[now]|v==son[now])continue;
dfs_2(v,v);
}
return ;
}
int mi[maxn<<2];
void build(int now,int l,int r){
if(l==r){
mi[now]=w[rnk[l]];
return ;
}
int mid=(l+r)>>1;
build(now<<1,l,mid);
build(now<<1|1,mid+1,r);
mi[now]=min(mi[now<<1],mi[now<<1|1]);
return ;
}
int L,R;
int query(int now,int l,int r){
if(L<=l&&r<=R){
return mi[now];
}
int ans=inf,mid=(l+r)>>1;
if(L<=mid)ans=min(ans,query(now<<1,l,mid));
if(mid<R)ans=min(ans,query(now<<1|1,mid+1,r));
return ans;
}
inline int query_path(int x,int y){
int ans=inf;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])swap(x,y);
L=dfn[top[x]],R=dfn[x];
ans=min(ans,query(1,1,n));
x=fa[top[x]];
}
if(dfn[x]>dfn[y])swap(x,y);
L=dfn[x]+1,R=dfn[y];
if(L>R)return ans;
ans=min(ans,query(1,1,n));
return ans;
}
int main(){
int q,x,y,z;
read(n),read(m);
for(ri i=1;i<=m;i++){
read(x),read(y),read(z);
edge[i]=Edge(x,y,z);
}
kruskal();
for(ri i=1;i<=n;i++){//不一定联通
if(!dfn[i]){
dep[i]=1,fa[i]=0;
dfs_1(i);
dfs_2(i,i);
}
}
build(1,1,n);
read(q);
while(q--){
read(x),read(y);
int tmp=query_path(x,y);
if(!tmp)puts("-1");
else printf("%d\n",tmp);
}
return 0;
}
luogu题解P1967货车运输--树链剖分的更多相关文章
- P1967 货车运输 树链剖分
题目描述 AA国有nn座城市,编号从 11到nn,城市之间有 mm 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 qq 辆货车在运输货物, 司机们想知道每辆车在不超过车辆限重的情况下,最 ...
- luogu题解P2486[SDOI2011]染色--树链剖分+trick
题目链接 https://www.luogu.org/problemnew/show/P2486 分析 看上去又是一道强行把序列上问题搬运到树上的裸题,然而分析之后发现并不然... 首先我们考虑如何在 ...
- luogu题解 P3950部落冲突--树链剖分
题目链接 https://www.luogu.org/problemnew/show/P3950 分析 大佬都用LCT,我太弱只会树链剖分 一个很裸的维护边权树链剖分题.按照套路,对于一条边\(< ...
- 【Luogu】P3313旅行(树链剖分)
题目链接 动态开点的树链剖分qwq. 跟小奇的花园一模一样,不做过多讲解. #include<cstdio> #include<cstring> #include<cct ...
- Luogu 3384 【模板】树链剖分
题目描述 如题,已知一棵包含N个结点的树(连通且无环),每个节点上包含一个数值,需要支持以下操作: 操作1: 格式: 1 x y z 表示将树从x到y结点最短路径上所有节点的值都加上z 操作2: 格式 ...
- 树链剖分 - Luogu 3384【模板】树链剖分
[模板]树链剖分 题目描述 已知一棵包含N个结点的树(连通且无环),每个节点上包含一个数值,需要支持以下操作: 操作1: 格式: 1 x y z 表示将树从x到y结点最短路径上所有节点的值都加上z 操 ...
- Luogu P3178 树上操作(树链剖分+线段树)
题意 见原题 题解 重链剖分模板题 #include <cstdio> #include <algorithm> using std::swap; typedef long l ...
- 【Luogu】P3979遥远的国度(树链剖分)
题目链接 不会换根从暑假开始就困扰我了……拖到现在…… 会了还是很激动的. 换根操作事实上不需要(也不能)改树剖本来的dfs序……只是在query上动动手脚…… 设全树的集合为G,以root为根,u在 ...
- 题解 P1967 货车运输
题目描述 A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 q 辆货车在运输货物,司机们想知道每辆车在不超过车辆限重的情况下,最多能 ...
随机推荐
- keras检查点的保存
来自 keras的文档:https://keras.io/callbacks/#callback ModelCheckpoint keras.callbacks.ModelCheckpoint(fil ...
- lua table操作
求最大值,最小值及长度: function maxn(t) local mn = nil for i, v in pairs(t) do if (mn==nil) then mn=v end if ( ...
- 阶段5 3.微服务项目【学成在线】_day16 Spring Security Oauth2_01-用户认证需求分析
1.1 用户认证与授权 截至目前,项目已经完成了在线学习功能,用户通过在线学习页面点播视频进行学习.如何去记录学生的学习过程 呢?要想掌握学生的学习情况就需要知道用户的身份信息,记录哪个用户在什么时间 ...
- java通过telnet远程至windows机器执行dos命令
准备工作,远程windows机器中开启telnet服务,将远程登录用户添加至telnetClients用户组 核心代码: import java.io.IOException; import java ...
- (一)深入java虚拟机之内存溢出与分析
一.内存溢出程序 public class Test { public static void main(String[] args) { List<User> userList=new ...
- MySQL创建及删除临时表
示例SQL: drop temporary table if exists testdb.tmp_test_table; create temporary table testdb.tmp_test_ ...
- .Net Core 3.0 关于Windows Form和WPF的全面支持
引言 ".NET 核心是开源和跨平台.您可以使用 .NET Core 在 Windows.Mac.十几个 Linux.iPhone.IoT 设备等上运行服务器应用程序! .NET 酷睿是开源 ...
- darknet标签转化为COCO标签
import sys import json import cv2 import os import shutil dataset = { "info": { "desc ...
- 移动架构-json解析框架
JSON在现在数据传输中占据着重要地位,相比于xml,其解析和构成都要简单很多,第三方的解析框架也不胜枚举,这里之所以要自定义一个json解析框架,一方面是更好的了解json解析过程,另一方面是有时候 ...
- Evaluating Automatically Generated timelines from the Web (paper1)
摘要: 问题:There is a need that 以一个更全面/更综合的方式来展现搜索结果.对此,作者正在开发一个系统,called “Cronopath”,这个系统将产生一个时间线,通过决定每 ...