货车运输(LCA+最大生成树)
恩,这是一道神奇的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+最大生成树)的更多相关文章
- NOIP2013 货车运输(最大生成树,倍增)
NOIP2013 货车运输(最大生成树,倍增) A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 q 辆货车在运输货物,司机们想知道 ...
- NOIP2013 货车运输 (最大生成树+树上倍增LCA)
死磕一道题,中间发现倍增还是掌握的不熟 ,而且深刻理解:SB错误毁一生,憋了近2个小时才调对,不过还好一遍AC省了更多的事,不然我一定会疯掉的... 3287 货车运输 2013年NOIP全国联赛提高 ...
- 「NOIP2013」「LuoguP1967」货车运输(最大生成树 倍增 LCA
题目描述 AA国有nn座城市,编号从 11到nn,城市之间有 mm 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 qq 辆货车在运输货物, 司机们想知道每辆车在不超过车辆限重的情况下,最 ...
- [洛谷 P1967] 货车运输 (最大生成树 lca)
题目描述 A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 q 辆货车在运输货物, 司机们想知道每辆车在不超过车辆限重的情况下,最多 ...
- 货车运输(最大生成树+倍增LCA)
看到第一篇题解的神奇码风--我决定发一篇码风正常的题解造福人类 这题的做法也非常经典,最大生成树\(+LCA\),相当于先贪心一下,在LCA的时候记录一下当前最小的边权 顺便吐槽一下最后一个测试点: ...
- 【洛谷1967】货车运输(最大生成树+倍增LCA)
点此看题面 大致题意: 有\(n\)个城市和\(m\)条道路,每条道路有一个限重.多组询问,每次询问从\(x\)到\(y\)的最大载重为多少. 一个贪心的想法 首先,让我们来贪心一波. 由于要求最大载 ...
- NOIP2013D1T3货车运输(最大生成树+倍增lca)
传送门 这道题,先用kruskal求一遍图中的最大生成树. 然后,倍增求lca,求lca的同时求出边权的最小值. #include <cstring> #include <cstdi ...
- NOIP2013 货车运输 LCA倍增+最大生成树
#include <cstdio> #include <iostream> #include <ctime> #include <vector> #in ...
- NOIP2013货车运输[lca&&kruskal]
题目描述 A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 q 辆货车在运输货物, 司机们想知道每辆车在不超过车辆限重的情况下,最多 ...
- [NOIP2013/Codevs3287]货车运输-最小[大]生成树-树上倍增
Problem 树上倍增 题目大意 给出一个图,给出若干个点对u,v,求u,v的一条路径,该路径上最小的边权值最大. Solution 看到这个题第一反应是图论.. 然而,任意路径最小的边权值最大,如 ...
随机推荐
- VIM安装YCM插件
折腾了两天,终于好了 1.配置VIM (1)下载相关插件 sudo apt-get install git sudo apt-get install build-essential cmake sud ...
- 如何让button保持点击状态
http://blog.csdn.net/u010957508/article/details/38385207 他的原理就是在代码里面: view.setSelected(true); 而其他的: ...
- RandomAecessFile open failed: EISDIR (Is a directory)
今天下午搞断点续传,下载文件的时候,弄了一下,我把下载的文件命名为plug.jar.后来老是报错: open failed: EISDIR (Is a directory) 我烦了,两个小时啊,我操. ...
- python几个复习例子
1.实现1-100的所有的和,程序代码如下: sum = 0 for i in xrange(1,101): sum +=i print (sum) 程序运行结果: 2.实现1-500所有奇数的和,程 ...
- oracle 用户被锁定解锁方法
修改了用户密码,第二天过来发现用户被锁定,晚上走的时候还好好的 . alter profile DEFAULT limit FAILED_LOGIN_ATTEMPTS UNLIMITED; alter ...
- laravel5.5缓存系统
目录 1 Redis的配置 1.1 安装PRedis 1.2 配置 1.2.1 配置redis数据库 1.2.2 更改session的配置 1.2.3 更改cache配置 1.3 使用redis 2 ...
- 剑指Offer - 九度1351 - 数组中只出现一次的数字
剑指Offer - 九度1351 - 数组中只出现一次的数字2013-11-23 01:23 题目描述: 一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字. ...
- 手把手教你写Windows 64位平台调试器
本文网页排版有些差,已上传了doc,可以下载阅读.本文中的所有代码已打包,下载地址在此. ------------------------------------------------------- ...
- Kotlin中的“忍者”函数 —— 理解泛型的能力(KAD 12)
作者:Antonio Leiva 时间:Feb 8, 2017 原文链接:https://antonioleiva.com/generic-functions-kotlin/ Kotlin的一些特性组 ...
- python杂七杂八知识点
1.中文编码问题解决办法:# _*_ coding:UTF8 _*_ 2.numpy.ndArray a = array([[1,2,3], [4, 5, 6]]) 3.numpy.argsort() ...