货车运输-洛谷-1967-LCA+最大生成树(kruskal(并查集))
一道:LCA+最大生成树
个人认为把这两个的板子写好(并熟练掌握了之后)就没什么难的
(但我还是de了好久bug)qwq
最大生成树:其实就是最小生成树的变形
我用的是kruskal
(个人觉得kruskal比较好像and好写)
所以
对于kruskal而言
只是把边从小到大排序改成从大到小序就可以了
需要多维护一个w[ i ][ j ]数组
用来存从i点向上走j^2次步这个过程中最大承重量
透
又是数组开小了
(明明我算的不用那么大的啊qwq)
向现实低头
#include<cstdio>
#include<algorithm>
#define INF 999999999
using namespace std;
inline int read()//快读
{
int sum = ,p = ;
char ch = getchar();
while(ch < '' || ch > '')
{
if(ch == '-')
p = -;
ch = getchar();
}
while(ch >= '' && ch <= '')
{
(sum *= )+= ch - '';
ch = getchar();
}
return sum * p;
} const int maxn = ,maxm = ;
int n,m,cnt;
int head[maxn],deep[maxn],f[maxn][],fa[maxn],w[maxn][];
bool vis[maxn]; struct edge1
{
int from,to,wei;
}e1[maxm]; struct edge2
{
int next,to,wei;
}e2[maxm*]; bool cmp(edge1 a,edge1 b)
{
return a.wei > b.wei;
} int find(int o)
{
if(o == fa[o])
return o;
else
return fa[o] = find(fa[o]);
} void add(int x,int y,int z)
{
e2[++cnt].next = head[x];
e2[cnt].to = y;
e2[cnt].wei = z;
head[x] = cnt;
} void kruskal()
{
sort(e1+,e1+m+,cmp);
for(int i = ;i <= n;i++)
fa[i] = i;//并查集初始化:每个节点各为一个子树,即每个点的父节点都是他自己
int v,u;
for(int i = ;i <= m;i++)
{
u = find(e1[i].from);
v = find(e1[i].to);
if(u == v)//如果两个点已经在一个图中了,即这两个点已经有一个最大的边加入到生成树中了,那么再加进去就会生成环,所以不能加
continue;
fa[u] = v;//把v加入到生成树中
add(e1[i].from,e1[i].to,e1[i].wei);
add(e1[i].to,e1[i].from,e1[i].wei);//无向图,双向加边
}
return;
} void dfs(int o)
{
vis[o] = true;
for(int i = head[o];i;i = e2[i].next)
{
int to = e2[i].to;
if(vis[to])
continue;
deep[to] = deep[o] + ;
f[to][] = o;
w[to][] = e2[i].wei;
dfs(to);
}
} int lca(int x,int y)
{
if(find(x) != find (y))
return -;
int ans = INF;
if(deep[x] > deep[y])
swap(x,y);
for(int i = ;i >= ;i--)
if(deep[f[y][i]] >= deep[x])
{
ans = min(ans,w[y][i]);
y = f[y][i];
}
if(x == y)
return ans;
for(int i = ;i>=;i--)
if(f[x][i] != f[y][i])
{
ans = min(ans,min(w[x][i],w[y][i]));
x = f[x][i];
y = f[y][i]; }
ans = min(ans,min(w[x][], w[y][]));
return ans;
} int main()
{
n = read(),m = read();
int x,y,z;
for(int i = ;i <= m;i++)
{
x = read(),y = read(),z = read();
e1[i].from = x;
e1[i].to = y;
e1[i].wei = z;
}
kruskal();
for(int i = ;i <= n;i++)
if(!vis[i])
{
deep[i] = ;
dfs(i);
f[i][] = i;
w[i][] = INF;
}
for(int i = ;i <= ;i++)
for(int j = ;j <= n;j++)
{
f[j][i]=f[f[j][i-]][i-];
w[j][i]=min(w[j][i-], w[f[j][i-]][i-]);
}
int q = read();
for(int i = ;i <= q;i++)
{
x = read(),y = read();
printf("%d\n",lca(x,y));
}
return ;
}
货车运输-洛谷-1967-LCA+最大生成树(kruskal(并查集))的更多相关文章
- Codevs 3287 货车运输 == 洛谷P1967
3287 货车运输 2013年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description A 国有 n 座城市,编 ...
- 洛谷P4004 Hello world!(分块+并查集)
传送门 虽然洛谷数据水,然而咱最终还是没有卡过uoj上的毒瘤数据-- 神tm全uoj就3个人过了这题-- 首先,每个数最多被开根\(6\)次,开到\(1\)之后就别管它了,把它用并查集连到它父亲上 它 ...
- 洛谷P3247 [HNOI2016]最小公倍数 [分块,并查集]
洛谷 思路 显然,为了达到这个最小公倍数,只能走\(a,b\)不是很大的边. 即,当前询问的是\(A,B\),那么我们只能走\(a\leq A,b\leq B\)的边. 然而,为了达到这最小公倍数,又 ...
- Bzoj5188/洛谷P4185 [Usaco2018 Jan]MooTube(并查集)
题面 Bzoj 洛谷 题解 最暴力的方法是直接判两个点之间的路径最小值是否\(\geq k\),用\(Dijkstra\)可以做到该算法最快效率,但是空间复杂度始终是\(O(n^2)\)的,会\(ML ...
- 洛谷P1196 银河英雄传说[带权并查集]
题目描述 公元五八○一年,地球居民迁移至金牛座α第二行星,在那里发表银河联邦 创立宣言,同年改元为宇宙历元年,并开始向银河系深处拓展. 宇宙历七九九年,银河系的两大军事集团在巴米利恩星域爆发战争.泰山 ...
- [洛谷P1197/BZOJ1015][JSOI2008]星球大战Starwar - 并查集,离线,联通块
Description 很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治者整个星系.某一天,凭着一个偶然的机遇,一支反抗军摧毁了帝国的超级武器,并攻下了星系中几乎所有的星球.这些星球通过 ...
- 【洛谷P3224】永无乡 并查集+Splay启发式合并
题目大意:给定 N 个点的图,点有点权,初始有一些无向边,现在有 Q 个询问,每个询问支持动态增加一条无向边连接两个不连通的点和查询第 X 个点所在的联通块中权值第 K 大的是哪个点. 题解:学会了平 ...
- 洛谷P4768 [NOI2018]归程 [可持久化并查集,Dijkstra]
题目传送门 归程 格式难调,题面就不放了. 分析: 之前同步赛的时候反正就一脸懵逼,然后场场暴力大战,现在呢,还是不会$Kruskal$重构树,于是就拿可持久化并查集做. 但是之前做可持久化并查集的时 ...
- 【洛谷】P1196 银河英雄传说(并查集)
题目描述 公元五八○一年,地球居民迁至金牛座α第二行星,在那里发表银河联邦创立宣言,同年改元为宇宙历元年,并开始向银河系深处拓展. 宇宙历七九九年,银河系的两大军事集团在巴米利恩星域爆发战争.泰山压顶 ...
随机推荐
- ldap配置系列三:grafana集成ldap
ldap配置系列三:grafana集成ldap grafana的简介 grafana是一个类似kibana的东西,是对来自各种数据源的数据进行实时展示的平台,拥有这牛逼的外观.给一个官方的demo体验 ...
- 痞子衡嵌入式:第一本Git命令教程(1)- 准备(init/config/.gitignore)
今天是Git系列课程第一课,痞子衡给大家要讲的是创建仓库的准备工作. 1.建仓库git init 第一步是创建一个空仓库,这是一切操作的前提. // 打开git bash命令行,切换到指定目录下 ja ...
- VS2017移动开发(C#、VB.NET)——Numeric控件的使用方式
Visual Studio 2017移动开发 控件介绍和使用方式:Numeric控件 Smobiler开发平台,.NET移动开发 一. 样式一 我们要实现上图中的效果,需要如下的操作 ...
- .Net Core 实践 - 使用log4net记录日志(1)
demo地址:https://github.com/PuzzledAlien/log4net_demo 准备 log4net 最新版本是2.0.8 VS2017 .Net Core 2.2 测试电脑配 ...
- 消息队列_MSMQ(2)简单应用
上一篇讲了MSMQ的简单知识,那这次我们讲下简单代码的知识 附上源码: https://gitee.com/592576605/MSMQ_HANS 下面是简单的类库说明,具体咋用就看源码吧 类(Cla ...
- spring boot 页面根路径获取和jsp获取的不同之处(粘贴即用)
不同之处已做高亮. jsp 写法: <script type="text/javascript" src="${pageContext.request.contex ...
- Linux设置Swap虚拟内存方法
linux可以文件或者分区来当作虚拟内存. 首先查看当前的内存和swap 空间大小(默认单位为k, -m 单位为M): free -m 查看swap信息,包括文件和分区的详细信息 swapon -s或 ...
- Linux下Jenkins服务器搭建
系统环境 操作系统:CentOS6.9 java jdk:java 8 Jenkins版本:jenkins-2.78-1.1.noarch.rpm 关闭防火墙 注意:如果是基于msbuild构建.ne ...
- git 常用命令,上传,下载,更新线上代码
git 常用命令以及推荐git新建上传个人博客 $ git clone //本地如果无远程代码,先做这步,不然就忽略 $ git status //查看本地自己修改了多少文件 $ git add . ...
- 51nod“省选”模测第二场 B 异或约数和(数论分块)
题意 题目链接 Sol 这题是来搞笑的吧.. 考虑一个数的贡献是\(O(\frac{N}{i})\) 直接数论分块. #include<bits/stdc++.h> #define Pai ...