kruskal - 倍增 - 并查集 - Luogu 1967 货车运输
P1967 货车运输
题目描述
A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路。每一条道路对车辆都有重量限制,简称限重。现在有 q 辆货车在运输货物, 司机们想知道每辆车在不超过车辆限重的情况下,从一个地方到另一个地方最多能运多重的货物。
说明
对于 100%的数据,0 < 城市数n < 10,000,0 < 道路数m < 50,000,0 < 询问数q< 30,000,0 ≤ 限重z ≤ 100,000。
鉴于这是个稀疏图,我们用kruskal。
最小生成树有一个定理,就是边集中最大的边最小。
那么我们魔改一下kruskal使它变成求最大生成树,就有最小边最大的定理。
之后就可以通过一些手段来处理造出来的生成树了
树链剖分辣么长,懒得打
所以博主这儿用的倍增
f1[i][j]表示i点往上跳2^j距离到达的点
f2[i][j]表示i点往上跳2^j距离的路径上的最小值
就可以暴力求LCA辣啊哈哈哈哈
这里推荐一个更快的大佬code-> http://www.cnblogs.com/xzz_233/p/7614189.html .
代码蒯上
#include<iostream>
#include<iomanip>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
inline int gotcha()
{
register int _a=0;bool _b=1;register char _c=getchar();
while(_c<'0' || _c>'9'){if(_c=='-')_b=0;_c=getchar();}
while(_c>='0' && _c<='9')_a=_a*10+_c-48,_c=getchar();
return _b?_a:-_a;
}
const int _ = 10002;
using namespace std;
struct edge{int to,ne,len;edge(){to=ne=len=0;}}e[10*_];
struct sav
{
int fr,to,len;sav(){fr=to=len=0;}
const bool operator < (const sav &b)const{return len>b.len;}
}tp[5*_];
int he[_],ecnt=0,dep[_],f1[_][18],f2[_][18],n,m,fa[_],gfa[_];
void add(int fr,int to,int len)
{e[++ecnt].to=to,e[ecnt].len=len,e[ecnt].ne=he[fr],he[fr]=ecnt;}
int finder(int a){return gfa[a]!=a?gfa[a]=finder(gfa[a]):a;}
void link(int a,int b){gfa[finder(b)]=finder(a);}
void plant(int a)
{
for(int i=he[a],j;i;i=e[i].ne)
{
j=e[i].to;if(j==fa[a])continue;
fa[j]=a,f1[j][0]=a,f2[j][0]=e[i].len,dep[j]=dep[a]+1,plant(j);
}
}
int driver(int st,int ta)
{
register int i,mi=2e9;
if(dep[st]>dep[ta])
for(i=16;i>=0;i--)if(f1[st][i]!=0 && dep[f1[st][i]]>=dep[ta])
mi=min(mi,f2[st][i]),st=f1[st][i];
if(dep[ta]>dep[st])
for(i=16;i>=0;i--)if(f1[ta][i]!=0 && dep[f1[ta][i]]>=dep[st])
mi=min(mi,f2[ta][i]),ta=f1[ta][i];
if(st==ta)return mi;
for(i=16;i>=0;i--)if(f1[st][i]!=f1[ta][i])
mi=min(mi,min(f2[st][i],f2[ta][i])),st=f1[st][i],ta=f1[ta][i];
return min(mi,min(f2[st][0],f2[ta][0]));
}
int main()
{
register int i,j,k;
n=gotcha(),m=gotcha();
for(i=1;i<=n;i++)gfa[i]=i;
for(i=1;i<=m;i++)tp[i].fr=gotcha(),tp[i].to=gotcha(),tp[i].len=gotcha();
sort(tp+1,tp+m+1);
for(i=1;i<=m;i++)
if(finder(tp[i].fr)!=finder(tp[i].to))
{
link(tp[i].fr,tp[i].to);
add(tp[i].fr,tp[i].to,tp[i].len),add(tp[i].to,tp[i].fr,tp[i].len);
}
for(i=1;i<=n;i++)if(i==gfa[i])fa[i]=i,dep[i]=1,plant(i);
for(i=1;i<=16;i++)
for(j=1;j<=n;j++)
{
f1[j][i]=f1[f1[j][i-1]][i-1];
f2[j][i]=min(f2[j][i-1],f2[f1[j][i-1]][i-1]);
}
i=gotcha();
while(i--)
{
j=gotcha(),k=gotcha();
printf("%d\n",(finder(j)==finder(k)?driver(j,k):-1));
}
return 0;
}
kruskal - 倍增 - 并查集 - Luogu 1967 货车运输的更多相关文章
- [luogu 1967]货车运输
货车运输 题目描述 A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 q 辆货车在运输货物, 司机们想知道每辆车在不超过车辆限重的情 ...
- luogu 1967 货车运输(最大生成树+LCA)
题意:给出一颗n个点的图,q个询问,每次询问u到v的路径中最小的边最大是多少. 图的最大生成树有一个性质,对于该图的任意两个点,在树中他们之间路径的最小边最大. 由于这个图不一定联通,于是我们对它的联 ...
- 洛谷P3295 萌萌哒 [SCOI2016] 倍增+并查集
正解:倍增+并查集 解题报告: 传送门! 首先不难想到暴力?就考虑把区间相等转化成对应点对相等,然后直接对应点连边,最后求有几个连通块就好辣 然后看下复杂度,修改是O(n2)查询是O(n),就比较容易 ...
- 最小生成树(Minimum Spanning Tree)——Prim算法与Kruskal算法+并查集
最小生成树——Minimum Spanning Tree,是图论中比较重要的模型,通常用于解决实际生活中的路径代价最小一类的问题.我们首先用通俗的语言解释它的定义: 对于有n个节点的有权无向连通图,寻 ...
- 货车运输-洛谷-1967-LCA+最大生成树(kruskal(并查集))
传送门 一道:LCA+最大生成树 个人认为把这两个的板子写好(并熟练掌握了之后)就没什么难的 (但我还是de了好久bug)qwq 最大生成树:其实就是最小生成树的变形 我用的是kruskal (个人觉 ...
- Luogu P1967 货车运输(Kruskal重构树)
P1967 货车运输 题面 题目描述 \(A\) 国有 \(n\) 座城市,编号从 \(1\) 到 \(n\) ,城市之间有 \(m\) 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 \ ...
- [SCOI2016]萌萌哒(倍增+并查集)
一个长度为n的大数,用S1S2S3...Sn表示,其中Si表示数的第i位,S1是数的最高位,告诉你一些限制条件,每个条件表示为四个数,l1,r1,l2,r2,即两个长度相同的区间,表示子串Sl1Sl1 ...
- 【BZOJ 4569】 4569: [Scoi2016]萌萌哒 (倍增+并查集)
4569: [Scoi2016]萌萌哒 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 865 Solved: 414 Description 一个长 ...
- 模板——最小生成树kruskal算法+并查集数据结构
并查集:找祖先并更新,注意路径压缩,不然会时间复杂度巨大导致出错/超时 合并:(我的祖先是的你的祖先的父亲) 找父亲:(初始化祖先是自己的,自己就是祖先) 查询:(我们是不是同一祖先) 路径压缩:(每 ...
随机推荐
- 【持续更新】MyBatis相关
MyBatis开发结构 #与$的区别
- 韦东山笔记之安装arm-linux-gcc交叉编译环境详细步骤。
1在关盘主目录tools下复制arm-linux-gcc-3.4.5-glibc-2.3.6.tar.bz2到虚拟机上 解压 tar xjf arm-linux-gcc-3.4.5-glibc ...
- 零基础逆向工程18_PE结构02_联合体_节表_PE加载过程
联合体 特点 1.联合体的成员是共享内存空间的 2.联合体的内存空间大小是联合体成员中对内存空间大小要求最大的空间大小 3.联合体最多只有一个成员有效 节表数据结构说明 PE 加载 过程 FileBu ...
- 零基础逆向工程12_C语言06_switch语句反汇编
12_C语言06_switch语句反汇编 switch语句反汇编 测试环境:VC++6.0 分支少于4的时候没有意义,编译器会生成类似if...else之类的反汇编,不超过三个分支,不会生成索引表. ...
- Android 4.4及以后将内容布局延伸到状态栏
首先说明:该文章不是大家说的沉浸式状态栏,网上沉浸式状态栏的博客很多,搜索就有了! 该篇博客的主要目的就是为了将图片显示在状态栏上,让APP看起来更有型!如下图所示: 界面 这个界面的布局就是co ...
- pytest+allure2+jenkins环境部署
1.pycharm安装allure-pytest 2.jenkins -> 系统管理 -> 插件管理 -> 可选插件中过滤Allure,勾选对应插件安装 如下图: 3.安装完插件后 ...
- 内容导出成word
private void 导出word(string 内容) { string tit = "<html xmlns:v=\"urn:schemas-microsoft-co ...
- 【TensorFlow入门完全指南】模型篇·线性回归模型
首先呢,进行import,对于日常写代码来说,第二行经常写成:import numpy as np,这样会更加简洁.第三行import用于绘图. 定义了学习率.迭代数epoch,以及展示的学习步骤,三 ...
- 使用ABAP批量下载有道云笔记中的图片
Jerry喜欢用有道云笔记这款软件做自己的知识管理和知识体系的构建. 当您看到一篇好的有道云笔记分享时,可能会想将其精美的图片下载到本地.作为程序猿,我们不会去手动一张张下载.写个程序帮我们自动下载吧 ...
- 【转】实用API大全
有道翻译APIhttp://fanyi.youdao.com/openapi有道翻译API支持中英互译,同时获得有道翻译结果和有道词典结果(可能没有),返回格式为XML或JSON. 百度翻译APIht ...