Luogu 1111 修复公路(最小生成树)
Luogu 1111 修复公路(最小生成树)
Description
A地区在地震过后,连接所有村庄的公路都造成了损坏而无法通车。政府派人修复这些公路。
给出A地区的村庄数N,和公路数M,公路是双向的。并告诉你每条公路的连着哪两个村庄,并告诉你什么时候能修完这条公路。问最早什么时候任意两个村庄能够通车,即最早什么时候任意两条村庄都存在至少一条修复完成的道路(可以由多条公路连成一条道路)
Input
第1行两个正整数N,M
下面M行,每行3个正整数x, y, t,告诉你这条公路连着x,y两个村庄,在时间t时能修复完成这条公路。
Output
如果全部公路修复完毕仍然存在两个村庄无法通车,则输出-1,否则输出最早什么时候任意两个村庄能够通车。
Sample Input
4 4
1 2 6
1 3 4
1 4 5
4 2 3
Sample Output
5
Http
Luogu:https://www.luogu.org/problem/show?pid=1111
Source
最小生成树 并查集
题目大意
求图中满足所有点联通的边的集合中最大值最下(说得简单点,就是求一个图的最小生成树并输出树上的最大边)
解决思路
首先用克鲁斯卡尔算法求出最小生成树,具体做法是:
- 将所有的边按照边权值从小到大排序
- 从第一条边开始枚举,每次判断这条边的两端点,若都已经在一个连通块里了,跳过,若不在,连接这条边并合并这两个连通块
- 持续上述操作,直到连接了n-1条边(为什么是n-1条呢?因为一棵树的边就是n-1条啊)或是所有的边都扫描过了(此时代表无解,原图不连通)
那么现在的问题就是如何判断两个点已经在同一连通块中了呢?
没错!我们用并查集来判断连通块。
定义一个F[i](代码中用Mayuri[i])来表示i所属的并查集编号。开始时每一个点都是一个孤立的连通块,所以每一个F[i]=i。在合并两个点u,v时,只要将u,v所在的并查集合并就可以将两个连通块合并了,具体操作就是将F[u]置为F[v],但这样是有问题的,因为u所在的并查集编号并不一定是F[u],所以要一直向上搜寻,我们用一个Find()函数来表示,递归地找到最早的编号。
但是这样有可能出现树退化成链表的情况,所以在Find函数查找时,顺便压缩路径(具体请看代码)
代码
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
class Road
{
public:
int u,v,w;
};
bool operator < (Road a,Road b)//因为要排序,所以重载一下小于运算符
{
return a.w<b.w;
}
const int maxN=2000;
const int maxM=101000;
const int inf=2147483647;
int n,m;
int Mayuri[maxN];
Road E[maxM];
int Find(int x);
int main()
{
int Ans=0;
int cnt=0;
cin>>n>>m;
for (int i=1;i<=m;i++)
{
cin>>E[i].u>>E[i].v>>E[i].w;
}
sort(&E[1],&E[m+1]);
for (int i=1;i<=n;i++)//并查集初始化
Mayuri[i]=i;
int i=0;
do
{
i++;
int fu=Find(E[i].u);
int fv=Find(E[i].v);
if (fu!=fv)//如果u,v不在同一个连通块,就合并
{
cnt++;//统计选择了的边的个数,便于及时退出和判断是否有解
Ans=max(E[i].w,Ans);//更新答案
Mayuri[fu]=fv;
}
if (cnt==n-1)//当已经形成一个树时,及时退出循环
break;
}
while (i<m);
if (cnt==n-1)
cout<<Ans<<endl;
else
cout<<-1<<endl;
return 0;
}
int Find(int x)
{
if (Mayuri[x]!=x)
Mayuri[x]=Find(Mayuri[x]);//压缩路径,让每一个点都直接指向其并查集编号的那个点
return Mayuri[x];
}
Luogu 1111 修复公路(最小生成树)的更多相关文章
- Luogu P1265修复公路【Prim最小生成树】By cellur925
题目传送门 政府审批的规则如下: (1)如果两个或以上城市申请修建同一条公路,则让它们共同修建: (2)如果三个或以上的城市申请修建的公路成环.如下图,A申请修建公路AB,B申请修建公路BC,C申请修 ...
- [LUOGU] P1111 修复公路
题目背景 A地区在地震过后,连接所有村庄的公路都造成了损坏而无法通车.政府派人修复这些公路. 题目描述 给出A地区的村庄数N,和公路数M,公路是双向的.并告诉你每条公路的连着哪两个村庄,并告诉你什么时 ...
- 最小生成树 kruskal算法 codevs 1638 修复公路
1638 修复公路 时间限制: 1 s 空间限制: 256000 KB 题目等级 : 钻石 Diamond 题解 题目描述 Description A地区在地震过后,连接所有村庄的公 ...
- P1111 修复公路
P1111 修复公路 550通过 1.6K提交 题目提供者该用户不存在 标签并查集 难度普及/提高- 提交该题 讨论 题解 记录 题目背景 A地区在地震过后,连接所有村庄的公路都造成了损坏而无法通 ...
- [LuoguP1111]修复公路
[LuoguP1111]修复公路 题目描述: A地区在地震过后,链接所有村庄的公路都损坏了,而导致无法通车,政府派人修复这些公路. 给出A地区的N村庄数和M公路数,并且对于每一个公路给出其链接的两个村 ...
- 洛谷 P1111 修复公路(最小生成树)
嗯... 题目链接:https://www.luogu.org/problemnew/show/P1111 这道题的关键是读懂题: 首先根据题中的一些扎眼的字眼我们可以判断这是一道用最小生成树来做的题 ...
- (最小生成树 并查集)P1111 修复公路 洛谷
题目背景 A地区在地震过后,连接所有村庄的公路都造成了损坏而无法通车.政府派人修复这些公路. 题目描述 给出A地区的村庄数N,和公路数M,公路是双向的.并告诉你每条公路的连着哪两个村庄,并告诉你什么时 ...
- 洛谷 P1111 修复公路
题目链接 https://www.luogu.org/problemnew/show/P1111 以后只发题目链接!!! 题目大意 给出A地区的村庄数N,和公路数M,公路是双向的.并告诉你每条公路的连 ...
- P1111 修复公路 洛谷
https://www.luogu.org/problem/show?pid=1111 题目背景 A地区在地震过后,连接所有村庄的公路都造成了损坏而无法通车.政府派人修复这些公路. 题目描述 给出A地 ...
随机推荐
- 《实战java高并发程序设计》源码整理及读书笔记
日常啰嗦 不要被标题吓到,虽然书籍是<实战java高并发程序设计>,但是这篇文章不会讲高并发.线程安全.锁啊这些比较恼人的知识点,甚至都不会谈相关的技术,只是写一写本人的一点读书感受,顺便 ...
- java基础(十四章)
1.Java中的包(package) 2.1 包,对应到磁盘中的文件夹 2.2 新建一个class,默认保存在缺省包中 2.3 声明包的关键字:package package语句,置顶位置 2.4 导 ...
- js中年份、月份下拉框
<select id="year" style="width: 100px;"></select> <select id=&quo ...
- PHP的魔法方法
PHP将所有以__(两个下划线)开头的类方法保留为魔术方法.所以在定义方法是,除了魔术方法,建议不要用两个下划线前缀. 魔术方法(Magic methods)有 __construct(),__des ...
- idea live template高级知识, 进阶(给方法,类,js方法添加注释)(二)
上一篇文章(http://www.cnblogs.com/xzjxylophone/p/6994488.html) 是在 groovyScript中直接添加的代码,这个看起来是简单,粗暴,麻烦和不美观 ...
- ecshop屏蔽wap功能
用手机打开ecshop网店,就会被重定向到mobile文件夹,如果打开wap功能,就能看到wap版的网站.但现在智能手机横行,iphone.安卓可以跟电脑一样浏览和购物,这个wap功能就有点鸡肋.现在 ...
- v9 调用模型中新增的字段
在模型中新增字段的时候,可以选择“是否为主表”. 若选是,则前台调用可直接通过字段名调用. 若选否,在前台调用是应在{pc:content}中添加 moreinfo="1",表示允 ...
- 并发编程(三):全视角解析volatile
一.目录 1.引入话题-发散思考 2.volatile深度解析 3.解决volatile原子性问题 4.volatile应用场景 二.引入话题-发散思考 public class T1 { /*vol ...
- maven 不同环境加载不同的properties 文件
http://haohaoxuexi.iteye.com/blog/1900568 //参考文章 实际项目中pom配置如下 <profiles> <profile> <i ...
- MySQL数据表的创建、查看、插入
数据表:数据表(或称表)是数据库最重要的组成部分之一,是其他对象的基础. 1.首先我们打开一个数据库(这里我打开的是新创建的一个aaa数据库). 打开数据库:use + 数据库名; 2 ...