题目链接

  倍增LCA是个什么蛇皮原理啊,循环完了还得再往上跳一次才能到最近公共祖先

  合着我昨天WA两次就是因为这个

  建最大生成森林,因为图不一定是联通的,所以不一定是一棵树。这个地方用克鲁斯卡尔就好了

  然后给这个森林跑一遍DFS,顺便倍增

  然后对于每个询问跑LCA,倍增的时候已经顺便求出了最小边权,所以往上跳的同时更新答案。

  代码如下

#include<cstdio>
#include<cctype>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<cstring>
inline long long read(){
long long num=,f=;
char ch=getchar();
while(!isdigit(ch)){
if(ch=='-') f=-;
ch=getchar();
}
while(isdigit(ch)){
num=num*+ch-'';
ch=getchar();
}
return num*f;
} struct EDGE{
int from,to,dis;
bool operator <(const EDGE &a)const{
return dis>a.dis;
}
}que[]; int father[];
struct Edge{
int next,to,dis;
}edge[];
int head[],num;
inline void add(int from,int to,int dis){
edge[++num]=(Edge){head[from],to,dis};
head[from]=num;
} int find(int x){
if(father[x]!=x) father[x]=find(father[x]);
return father[x];
} inline void unionn(int x,int y){
x=find(x);y=find(y);
father[y]=x;
} int deep[];
int d[][];
int s[][]; void dfs(int x,int fa){
deep[x]=deep[fa]+;
for(int i=head[x];i;i=edge[i].next){
int to=edge[i].to;
if(to==fa) continue;
d[to][]=x;
s[to][]=edge[i].dis;
dfs(to,x);
}
}
int cnt;
int main(){
int n=read(),m=read();
for(int i=;i<=m;++i){
int from=read(),to=read(),dis=read();
que[i]=(EDGE){from,to,dis};
}
std::sort(que+,que+m+);
for(int i=;i<=n;++i) father[i]=i;
for(int i=;i<=m;++i){
int from=que[i].from,to=que[i].to,dis=que[i].dis;
if(find(from)==find(to)) continue;
unionn(from,to);
add(from,to,dis);
add(to,from,dis);
if(++cnt==n-) break;
}
for(int i=;i<=n;++i)
if(!deep[i]) dfs(i,i);
for(int j=;(<<j)<=n;++j)
for(int i=;i<=n;++i){
d[i][j]=d[d[i][j-]][j-];
s[i][j]=std::min(s[d[i][j-]][j-],s[i][j-]);
}
int Q=read();
for(int i=;i<=Q;++i){
int from=read(),to=read();
if(find(from)!=find(to)){
printf("-1\n");
continue;
}
if(deep[from]<deep[to]) std::swap(from,to);
int x=deep[from]-deep[to],ans=0x7fffffff;
for(int j=;(<<j)<=x;++j)
if((<<j)&x){
ans=std::min(ans,s[from][j]);
from=d[from][j];
}
if(from==to){
printf("%d\n",ans);
continue;
}
for(int j=log2(n);j>=;--j)
if(d[from][j]!=d[to][j]){
ans=std::min(ans,std::min(s[from][j],s[to][j]));
from=d[from][j];
to=d[to][j];
}
ans=std::min(ans,std::min(s[from][],s[to][]));
printf("%d\n",ans);
}
return ;
}

完毕。

【Luogu】P1967货车运输(最大生成森林+倍增LCA)的更多相关文章

  1. Luogu P1967 货车运输(Kruskal重构树)

    P1967 货车运输 题面 题目描述 \(A\) 国有 \(n\) 座城市,编号从 \(1\) 到 \(n\) ,城市之间有 \(m\) 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 \ ...

  2. 「NOIP2013」「LuoguP1967」货车运输(最大生成树 倍增 LCA

    题目描述 AA国有nn座城市,编号从 11到nn,城市之间有 mm 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 qq 辆货车在运输货物, 司机们想知道每辆车在不超过车辆限重的情况下,最 ...

  3. 货车运输(最大生成树+倍增LCA)

    看到第一篇题解的神奇码风--我决定发一篇码风正常的题解造福人类 这题的做法也非常经典,最大生成树\(+LCA\),相当于先贪心一下,在LCA的时候记录一下当前最小的边权 顺便吐槽一下最后一个测试点: ...

  4. 【洛谷1967】货车运输(最大生成树+倍增LCA)

    点此看题面 大致题意: 有\(n\)个城市和\(m\)条道路,每条道路有一个限重.多组询问,每次询问从\(x\)到\(y\)的最大载重为多少. 一个贪心的想法 首先,让我们来贪心一波. 由于要求最大载 ...

  5. Luogu P1967 货车运输 倍增+最大生成树

    看见某大佬在做,决定补一发题解$qwq$ 首先跑出最大生成树(注意有可能不连通),然后我们要求的就是树上两点间路径上的最小边权. 我们用倍增的思路跑出来$w[u][j]$,表示$u$与的它$2^j$的 ...

  6. LUOGU P1967 货车运输(最大生成树+树剖+线段树)

    传送门 解题思路 货车所走的路径一定是最大生成树上的路径,所以先跑一个最大生成树,之后就是求一条路径上的最小值,用树剖+线段树,注意图可能不连通.将边权下放到点权上,但x,y路径上的lca的答案不能算 ...

  7. Luogu P1967 货车运输

    qwq 这题是知道了正解做法才写的.. 求每两点间最小权值最大的路径,本来我以为要每个点都跑一遍dij(?),后来意识到生成树好像是用来找这个的( ´▽`) 然后我问dtxdalao对不对,他说“我记 ...

  8. NOIP2013D1T3货车运输(最大生成树+倍增lca)

    传送门 这道题,先用kruskal求一遍图中的最大生成树. 然后,倍增求lca,求lca的同时求出边权的最小值. #include <cstring> #include <cstdi ...

  9. 洛谷P3379lca,HDU2586,洛谷P1967货车运输,倍增lca,树上倍增

    倍增lca板子洛谷P3379 #include<cstdio> struct E { int to,next; }e[]; ],anc[][],log2n,deep[],n,m,s,ne; ...

随机推荐

  1. 详解ASP.NET缓存机制

    文中对ASP.NET的缓存机制进行了简述,ASP.NET中的缓存极大的简化了开发人员的使用,如果使用得当,程序性能会有客观的提升.缓存是在内存存储数据的一项技术,也是ASP.NET中提供的重要特性之一 ...

  2. Linux下的I/O复用

    读书笔记 I/O复用使得程序能同时监听多个文件描述符,这对提高程序的性能至关重要. Linux下实现I/O复用的系统调用主要有select, poll, epoll. select: 用户通过3个参数 ...

  3. 系统妈Win10系统64位和32位快速专业版

    win10系统64位快速专业安装版 V2016年 系统妈:http://www.xitongma.com/ Ghost Win10 64位正式装机专业版2016 微软向Windows用户推送了win1 ...

  4. POJ 1947 Rebuilding Roads (树形DP)

    题意:给一棵树,在树中删除一些边,使得有一个连通块刚好为p个节点,问最少需要删除多少条边? 思路: 因为任一条边都可能需要被删除,独立出来的具有p个节点的连通块可能在任意一处地方.先从根开始DFS,然 ...

  5. codevs 1390 回文平方数 USACO

    时间限制: 1 s  空间限制: 128000 KB  题目等级 : 青铜 Bronze 题目描述 Description 回文数是指从左向右念和从右像做念都一样的数.如12321就是一个典型的回文数 ...

  6. 根据HTML语义化编码

    语义化标签——http://www.html5jscss.com/html5-semantics-section.html 写HTML代码时应注意什么? 尽可能少的使用无语义的标签div和span: ...

  7. Robotium实践之路基于APK创建测试项目

    1.重新对包进行签名操作 .启动re-sign.jar文件 .找到相应的APK,拖拽置resigner中 2.创建基于APK测试的测试工程 .新建一个安卓测试项目 .选择this project

  8. Linux平台搭建roboframework

    安装步骤介绍: . 在Centos7..1503下,默认的python的版本2./site-packages/). 2.安装pip 第一步: ()下载setuptools包 # wget http:/ ...

  9. House of Spirit(fastbin)

    0x01 fastbin fastbin所包含chunk的大小为16 Bytes, 24 Bytes, 32 Bytes, … , 80 Bytes.当分配一块较小的内存(mem<=64 Byt ...

  10. DOM事件总结

    1.DOM事件: DOM0: element.onclick=function(){} DOM2: element.addEventListener(‘click’,function(){}) add ...