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算法+并查集数据结构
并查集:找祖先并更新,注意路径压缩,不然会时间复杂度巨大导致出错/超时 合并:(我的祖先是的你的祖先的父亲) 找父亲:(初始化祖先是自己的,自己就是祖先) 查询:(我们是不是同一祖先) 路径压缩:(每 ...
随机推荐
- zTree的重点
今天学习了zTree插件,记录一下使用步骤: 1 下载,把下载好的目录整个放在项目中 文件夹目录: js:一般引这jquery.ztree.all.js和jquery.ztree.core.js cs ...
- mysql(数据库,sql语句,普通查询)
第1章 数据库 1.1 数据库概述 l 什么是数据库 数据库就是存储数据的仓库,其本质是一个文件系统,数据按照特定的格式将数据存储起来,用户可以对数据库中的数据进行增加,修改,删除及查询操作. l 什 ...
- css3Transitions 实现的鼠标经过图标位移、旋转、翻转、发光、淡入淡出等多种特效
HTML如下: 1 <div class="container"> 3 <!--特效1 --> <section id="set-1&q ...
- uvm_mem_mam——寄存器模型(十三)
有了存储器模型,再来看看存储器的管理 //------------------------------------------------------------------------------ ...
- SQLSERVER是怎麽通过索引和统计信息来找到目标数据的(第三篇)
SQLSERVER是怎麽通过索引和统计信息来找到目标数据的(第三篇) 最近真的没有什么精力写文章,天天加班,为了完成这个系列,硬着头皮上了 再看这篇文章之前请大家先看我之前写的第一篇和第二篇 第一篇: ...
- asterisk-java ami2 事件监听
asteriskServer文章1提到啦怎么获取,就不解释 asteriskServer.addChainListener(new AsteriskeventListenerInit());//整个服 ...
- 使用tensorflow object_detection API训练自己的数据遇到的问题及解决方法
1.Windows下出现找不到object_detection包的问题. 解决方法 在Anaconda3\soft\Lib\site-packages新建一个pth文件,将PedestrianDete ...
- 如何真正解决“ UWP DEP0700: 应用程序注册失败。[0x80073CF9] 另一个用户已安装此应用的未打包版本。当前用户无法将该...”的问题
http://www.cnblogs.com/hupo376787/p/8267796.html 谈到了解决该问题的临时方案,那如何真正的解决该问题 目测可以开启设备门户来删除包
- 剑指offer15 链表中倒数第k个结点
错误代码 class Solution { public: ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) { ) retur ...
- mybatis association嵌套association的两级嵌套问题
今天遇到了一个双表连接查询以及自关联的问题,由于第一次遇到,所以在这记下,日后好查阅 针对一个表的关联属性本身也有自关联的情况下,可以用association嵌套association的方法来处理. ...