最大生成树——LCA
今天说是要练习LCA结果找了道题看着题解打完了,如此惭愧,Lca还得好好理解啊,感觉在最大生成树上做有点异样,可能还是不是很理解吧,在noip前一定要再把这道题再a一遍,好题啊。

这是2013noipt3的题,难度适中,比以往的简单没让人想不出来思路虽然我第一遍看也没想起来但是题解易懂,是我这种低级选手能做的题,所以今天下午选择做这道题,看着题解打了3h终于大功告成,一部分是抄的真心不会啊lca,昨天刚学还是打不下了。打完代码后按了下F7,嗯,100+errors真的很难受,代码能力过差,然后调试调了30多分钟,各种i打成j各种w打成fa,真的是醉了,按照汤神的话来说就是打代码的时候你在想什么,汤神看代码很准的基本上没什么错误orztql,于是乎和上一遍lca并不一样的不在于求最大生成树(这个非常好打)而是定根节点,要不这个最大的生成树可以看成一条线,如果不定根节点的话,谁知道你的最近公共祖先是谁,然后就是倍数的问题二进制的拆分,直接从20开始不必log(n)/log(i);因为n不可能超过2的20次方,尽管这样浪费一点时间,但是无关紧要,还有就是一点不是很理解的就是lca的初始化不是很懂啊,尽管明白那是个状态转移,但是呢打起来的时候还是迷茫,不理解内层因为i是从20开始的,于是乎到达很大的i的时候那时的祖先都是已经达到的祖先了这些都其实没什么用,还是写篇博客更好,又加深了理解,很棒呢!
下面是代码了接近150行代码=-= 好累。
#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<iomanip>
#include<algorithm>
#include<ctime>
#include<map>
#include<vector>
#include<stack>
#define inf 10000007
using namespace std;
inline int read()
{
int x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
const int maxn=;
struct bwy
{
int x,y,dis;
}s[maxn];
int e[maxn],nex[maxn],lin[maxn],ver[maxn],len;
int f[maxn],fa[maxn][],w[maxn][],depth[maxn],vis[maxn];
void add(int x,int y,int z)
{
ver[++len]=y;
nex[len]=lin[x];
lin[x]=len;
e[len]=z;
}
int n,m,k;
int my(bwy x,bwy y)
{
return x.dis>y.dis;
}
int getfather(int x)
{
if(x==f[x])
return x;
return f[x]=getfather(f[x]);
}
void kruskal()
{
for(int i=;i<=n;i++)
f[i]=i;
sort(s+,s++m,my);
for(int i=;i<=m;i++)
{
int xx=getfather(s[i].x);
int yy=getfather(s[i].y);
if(xx!=yy)
{
f[xx]=yy;
add(s[i].x,s[i].y,s[i].dis);
add(s[i].y,s[i].x,s[i].dis);
}
}
}
void dfs(int num)
{
vis[num]=;
for(int i=lin[num];i!=;i=nex[i])
{
int tn=ver[i];
if(vis[tn]==)
continue;
depth[tn]=depth[num]+;
fa[tn][]=num;
w[tn][]=e[i];
dfs(tn);
}
return;
}
int lca(int x,int y)
{
if(getfather(x)!=getfather(y))
return -;
int ans=inf;
if(depth[x]>depth[y])
swap(x,y);
for(int i=;i>=;i--)
{
if(depth[fa[y][i]]>=depth[x])
{
ans=min(ans,w[y][i]);
y=fa[y][i];
}
}
if(x==y)return ans;
for(int i=;i>=;i--)
{
if(fa[x][i]!=fa[y][i])
{
ans=min(ans,min(w[x][i],w[y][i]));
x=fa[x][i],y=fa[y][i];
}
}
ans=min(ans,min(w[x][],w[y][]));
return ans;
}
int main()
{
//freopen("1.in","r",stdin);
n=read();m=read();
for(int i=;i<=m;i++)
{
s[i].x=read();s[i].y=read();s[i].dis=read();
}
kruskal();
for(int i=;i<=n;i++)
{
if(vis[i]!=)
{
depth[i]=;
dfs(i);
fa[i][]=i;
w[i][]=inf;
}
}
for(int i=;i<=;i++)
for(int j=;j<=n;j++)
{
fa[j][i]=fa[fa[j][i-]][i-];
w[j][i]=min(w[j][i-],w[fa[j][i-]][i-]);
}
k=read();
for(int i=;i<=k;i++)
{
int x,y;
x=read();y=read();
cout<<lca(x,y)<<endl;
}
return ;
}
一天又过去,希望时间没白费。
最大生成树——LCA的更多相关文章
- bzoj3322 最大生成树+LCA
题目大意:给个无向图,每条边有个限制,每个点最多能买入和卖出一定黄金:然后按顺序走过n个点,求每个卖出黄金的点最多能卖出多少黄金 一开始有点懵,想着怎么再图上做这个问题,后来知道要先建一棵最大生成树 ...
- ACM-ICPC 2018 徐州赛区网络预赛 J Maze Designer(最大生成树+LCA)
https://nanti.jisuanke.com/t/31462 题意 一个N*M的矩形,每个格点到其邻近点的边有其权值,需要构建出一个迷宫,使得构建迷宫的边权之和最小,之后Q次查询,每次给出两点 ...
- ACM-ICPC 2018 徐州赛区网络预赛 J. Maze Designer 最大生成树 lca
大概就是要每两个点 只能有一条路径,并且约束,最短的边用来砌墙,那么反之的意思就是最大的边用来穿过 故最大生成树 生成以后 再用lca计算树上两点间的距离 (当然防止生成树是一条链,可以用树的重心作为 ...
- luogu 1967 货车运输(最大生成树+LCA)
题意:给出一颗n个点的图,q个询问,每次询问u到v的路径中最小的边最大是多少. 图的最大生成树有一个性质,对于该图的任意两个点,在树中他们之间路径的最小边最大. 由于这个图不一定联通,于是我们对它的联 ...
- 【NOIP2013】货车运输 最大生成树+LCA
题目描述 AA国有nn座城市,编号从 1到n,城市之间有m 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 q 辆货车在运输货物, 司机们想知道每辆车在不超过车辆限重的情况下,最多能运多重 ...
- [洛谷 P1967] 货车运输 (最大生成树 lca)
题目描述 A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 q 辆货车在运输货物, 司机们想知道每辆车在不超过车辆限重的情况下,最多 ...
- UVALive - 4960 Sensor network(生成树+LCA)
题目大意:给出N个点.M条边.问这N个点形成的生成树的最大权值边-最小权值边的最小值 解题思路:先排序,然后按生成树的kruscal算法进行加边,再维护一个最小权值边 加边的时候要考虑一下加下去的边是 ...
- P1967 货车运输[生成树+LCA]
题目描述 A国有n座城市,编号从 1到n,城市之间有 m 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 q* 辆货车在运输货物, 司机们想知道每辆车在不超过车辆限重的情况下,最多能运多重 ...
- ACM-ICPC 2018 徐州赛区网络预赛 J. Maze Designer (最大生成树+LCA求节点距离)
ACM-ICPC 2018 徐州赛区网络预赛 J. Maze Designer J. Maze Designer After the long vacation, the maze designer ...
随机推荐
- cocos2dx 3.0 scrollview 在android下面背景變綠色了
在windows上面跑的是OK的, 在android下面跑的時候就變成這樣子了:
- lua 按拉分析与合成
-- 将数值分解成bytes_table local function decompose_byte(data) if not data then return data end local tb = ...
- 【RF库Collections测试】lists should be equal
场景一:msg=None 场景二:自定义msg 场景三:自定义msg和values,且values为布尔类型False或者字符串False和No Values 场景四:自定义msg和values,且v ...
- Jsoup(三)-- Jsoup使用选择器语法查找DOM元素
1.Jsoup可以使用类似于CSS或jQuery的语法来查找和操作元素. 2.实例如下: public static void main(String[] args) throws Exception ...
- Splash plugins_enabled 属性
plugins_enabled属性可以控制浏览器插件(如 Flash 插件)是否开启.默认情况下,此属性是 false ,表示不开启. function main(splash, args) spla ...
- 资源打包Assetbundle .
在手游的运营过程中,更新资源是比不可少的.资源管理第一步是资源打包.传统的打包可以将所有物件制成预设Prefab,打包成场景.今天我们来一起学习官方推荐的Assetbundle,它是Unity(Pro ...
- spring applicationContext.xml 配置文件 详解
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://ww ...
- executeBatch()批量执行Sql语句
executeBatch()方法:用于成批地执行SQL语句,但不能执行返回值是ResultSet结果集的SQL语句,而是直接执行stmt.executeBatch(); addBatch():向批处理 ...
- Linux学习(二)
Linux进程管理 每个 Linux 命令都与系统中的程序对应,输入命令,Linux 就会创建一个新的进程.例如使用 ls 命令遍历目录中的文件时,就创建了一个进程.简而言之,进程就是程序的实例. 创 ...
- SharpGL学习笔记(三) 投影变换和视点变换
从本节开始,我们使用SharpGL带的VS2010扩展,来直接生成SharpGL工程. 如果你新建项目时,没有看到下面的SharpGL项目,那么请事先在SharpGL源代码中找到一个叫 ”SharpG ...