神奇传送门

恩,这是一道神奇的LCA+难度的题目。

题目是这样的:

A 国有n座城市,编号从1到n,城市之间有 m条双向道路。每一条道路对车辆都有重量限制,简称限重。现在有 q辆货车在运输货物,司机们想知道每辆车在不超过车辆限重的情况下,最多能运多重的货物。

一开始看了看,以为是费用流(PS:一看就是费用流裸题嘛。。)

然后发现有Q个询问。。

完美TLE

然后zxyer狠狠D了我一顿(%%%)这才发现写LCA是正解。。(太像了woc)

好吧,说正解。

这道题出现了Q个询问,我们很快就会想到RMQ和LCA

可是这道题是个图,不一定是树。

根据最大生成树的性质(载重量最大的那条路径一定在最大生成树上)

RMQ处理区间最小值,而LCA有个性质,就是它一定在U到V的最短路上,而且是2个点到根节点的路径的第一个交点。所以到了LCA就没必要往上走了,

因为路径是公共的,结果不会比LCA更优;

然后RMQ处理最小值,再找一下LCA,输出载重量最小值

然后就AC啦

原来程序有BUG(好吧。终于DEBUG出来了。。)

注意!写CMP函数时,如果用>=号会爆栈!

下面贴程序~

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int n,m,num=,q;
struct edge{
int next,to,value;
}g[];
int f[];
int depth[];
int visit[];
int fa[][];
int r[];
int u[],v[],w[];
int dist [][];
int head[];
int cmp(const int a,const int b) {
return w[a]>w[b];}
int getf(int x){
return x==f[x]?x:f[x]=getf(f[x]);}
void addedge(int u,int v,int value){
g[++num].next=head[u];
head[u]=num;
g[num].to=v;
g[num].value=value;
}
void kruskal(){
for(int i=;i<=n;i++) f[i]=i;
for(int i=;i<=m;i++) r[i]=i;
sort(r+,r+m+,cmp);
for(int i=;i<=m;i++)
{
int x=u[r[i]];
int y=v[r[i]];
x=getf(x);y=getf(y);
if(x!=y){
addedge(x,y,w[r[i]]);
addedge(y,x,w[r[i]]);
f[x]=y;
}
}
}
void prelca(int x){
visit[x]=;
for(int i=;(<<i)<=depth[x];i++)
{
int c=fa[x][i-];
fa[x][i]=fa[c][i-];
dist[x][i]=min(dist[x][i-],dist[c][i-]);
}
for(int i=head[x];i;i=g[i].next)
{
int v=g[i].to;
if(!visit[v])
{
depth[v]=depth[x]+;
fa[v][]=x;
dist[v][]=g[i].value;
prelca(v);
}
}
}
int lca(int x,int y)
{
int rr=;
if(depth[x]<depth[y])swap(x,y);
int dc=depth[x]-depth[y];
for(int i=;(<<i)<=dc;i++)
if(((<<i)&dc)&&fa[x][i])
{
rr=min(rr,dist[x][i]);
x=fa[x][i]; }
if(x==y)return rr;
for(int i=;i>=;i--)
if(fa[x][i]!=fa[y][i]&&depth[x]>=(<<i)&&fa[x][i])
{
rr=min(rr,min(dist[x][i],dist[y][i]));
x=fa[x][i];
y=fa[y][i];
}
return min(rr,min(dist[x][],dist[y][]));
}
int main(){
scanf("%d%d",&n,&m);
for(int i=;i<=m;i++)
scanf("%d%d%d",&u[i],&v[i],&w[i]);
kruskal();
for(int i=;i<=n;i++)
if(!visit[i])prelca(i);
scanf("%d",&q);
for(int i=;i<=q;i++)
{
int a,b;
scanf("%d%d",&a,&b);
if(getf(a)!=getf(b))printf("-1\n");
else printf("%d\n",lca(a,b));
}
return ;
}

注意:RMQ别打超限,调用空指针会WA的

货车运输(LCA+最大生成树)的更多相关文章

  1. NOIP2013 货车运输(最大生成树,倍增)

    NOIP2013 货车运输(最大生成树,倍增) A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 q 辆货车在运输货物,司机们想知道 ...

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

    死磕一道题,中间发现倍增还是掌握的不熟 ,而且深刻理解:SB错误毁一生,憋了近2个小时才调对,不过还好一遍AC省了更多的事,不然我一定会疯掉的... 3287 货车运输 2013年NOIP全国联赛提高 ...

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

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

  4. [洛谷 P1967] 货车运输 (最大生成树 lca)

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

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

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

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

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

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

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

  8. NOIP2013 货车运输 LCA倍增+最大生成树

    #include <cstdio> #include <iostream> #include <ctime> #include <vector> #in ...

  9. NOIP2013货车运输[lca&&kruskal]

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

  10. [NOIP2013/Codevs3287]货车运输-最小[大]生成树-树上倍增

    Problem 树上倍增 题目大意 给出一个图,给出若干个点对u,v,求u,v的一条路径,该路径上最小的边权值最大. Solution 看到这个题第一反应是图论.. 然而,任意路径最小的边权值最大,如 ...

随机推荐

  1. 17-比赛1 A - Weak in the Middle (栈)

    题目描述 给定长度为 N 的序列 A.每天,序列 A 中所有比两侧元素都小的元素都会消失.对于原序列中所有元素,请求出它会在第几天之后消失(天数从 1 开始计算),或者指出它不会消失. 数据范围 1 ...

  2. Android面试收集录6 事件分发机制

    转自:秋招面试宝典. 一. 基础认知 1.1 事件分发的对象是谁? 答:事件 当用户触摸屏幕时(View或ViewGroup派生的控件),将产生点击事件(Touch事件). Touch事件相关细节(发 ...

  3. 05,Python网络爬虫之三种数据解析方式

    回顾requests实现数据爬取的流程 指定url 基于requests模块发起请求 获取响应对象中的数据 进行持久化存储 其实,在上述流程中还需要较为重要的一步,就是在持久化存储之前需要进行指定数据 ...

  4. 关于 Google Chrome “Your connection is not private” 问题的处理

    今天下午访问google网站的时候,突然不能访问了,提示“Your connection is not private”(你的连接不是私密连接):查看XX-NET的设置,显示“请检查浏览器代理设置”. ...

  5. 《Cracking the Coding Interview》——第4章:树和图——题目4

    2014-03-19 03:40 题目:给定一棵二叉树,把每一层的节点串成一个链表,最终返回一个链表数组. 解法:前序遍历,遍历的同时向各个链表里添加节点.水平遍历好像还不如前序遍历来得方便. 代码: ...

  6. linux运维笔记

    一.查找大文件 sudo find / -size +100M -exec ls -lh {} \;

  7. android surfaceview 入门介绍

    由于工作中需自定义控件,以前没写过. 开始时,实用view 实现了,经理说不好,担心效率低,要求每秒需要刷新10次左右. 然后,学习使用  surfaceview. 看了网上简单的Demo,找到him ...

  8. 抓包工具 - Fiddler - (三)

    <转载自 miantest> 我们知道Fiddler是位于客户端和服务器之间的代理,它能够记录客户端和服务器之间的所有 HTTP请求,可以针对特定的HTTP请求,分析请求数据.设置断点.调 ...

  9. Python全栈工程师(运算符、if)

    ParisGabriel       Python 入门基础   比较运算符:< 小于<= 小于等于> 大于>= 大于等于== 等于!= 不等于 语法: 表达式1>表达式 ...

  10. lseek 与 ioctl

    lseek : 每个打开的文件都记录着当前读写位置,打开文件时读写位置是0,表示文件开头,通常读写多少个字节就会将读写位置往后移多少个字节.但是有一个例外,如果以O_APPEND方式打开,每次写操作都 ...