神奇传送门

恩,这是一道神奇的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. 解决win10子系统Ubuntu新装的mysql 不能root登陆方法

    步骤一:打开终端 $sudo /etc/init.d/mysql stop $sudo mkdir -p /var/run/mysqld $sudo chown mysql:mysql /var/ru ...

  2. win8电脑字体出现方格的解决方法

    一般电脑出现乱码有几种可能,最常见的可能就是电脑字体的丢失,其次就是电脑字体被病毒所损坏,因此,首先我们要做的就是下载字体并进行安装. 下载 simsun.tcc点击安装,如果电脑字体依然是这种情况( ...

  3. 554. Brick Wall

    class Solution { public: int leastBricks(vector<vector<int>>& wall) { unordered_map& ...

  4. 裸机——ADC

    1.首先是ADC的基本知识 模拟信号,连续的 数字信号,离散的 模拟信号,现实世界的很多东西都是连续的,所以使用模拟信号才能准确描述,但是模拟信号不方便控制. 数字信号,计算机中的信号大都为数字的,数 ...

  5. Background Segment CNT

    CNT简介 CNT算法是OpenCV Contrib 模块中的背景减除(Background segment)算法之一.相较于OpenCV提供的其他背景减 除算法,该算法具有运行速度快,检测精度高等优 ...

  6. 笔记-docker-2安装(centos6.5环境)

    笔记-docker-2安装(centos6.5环境) 1.      centos6.5安装docker 1.1.    升级内核 安装docker,官方文档要求linux kernel至少3.8以上 ...

  7. Oozie 之 sqoop 实战

    1.创建 lib 目录并拷贝 mysql 支持包 2.修改 job.properties 文件 nameNode=hdfs://cen-ubuntu.cenzhongman.com:8020 jobT ...

  8. Java文件 ---RandomAccessFile示例

    RandomAccessFile是用来访问那些保存数据记录的文件的,你就可以用seek( )方法来访问记录,并进行读写了.这些记录的大小不必相同:但是其大小和位置必须是可知的.但是该类仅限于操作文件 ...

  9. Java基本数据类型总结二

    Java 基本数据类型总结二 变量就是申请内存来存储值.也就是说,当创建变量的时候,需要在内存中申请空间. 内存管理系统根据变量的类型为变量分配存储空间,分配的空间只能用来储存该类型数据. 因此,通过 ...

  10. SpringBoot Rabbitmq发送消息

    官方文档:https://docs.spring.io/spring-boot/docs/2.1.3.RELEASE/reference/htmlsingle/#boot-features-amqp ...