算法笔记_180:历届试题 国王的烦恼(Java)
目录
1 问题描述
如果两个小岛间的所有大桥都不能使用,则这两座小岛就不能直接到达了。然而,只要这两座小岛的居民能通过其他的桥或者其他的小岛互相到达,他们就会安然无事。但是,如果前一天两个小岛之间还有方法可以到达,后一天却不能到达了,居民们就会一起抗议。
现在C国的国王已经知道了每座桥能使用的天数,超过这个天数就不能使用了。现在他想知道居民们会有多少天进行抗议。
接下来m行,每行三个整数a, b, t,分别表示该座桥连接a号和b号两个小岛,能使用t天。小岛的编号从1开始递增。
1 2 2
1 3 2
2 3 1
3 4 3
第二天后1和2之间,以及1和3之间的桥不能使用,居民们会抗议。
第三天后3和4之间的桥不能使用,居民们会抗议。
对于50%的数据,1<=n<=500,1<=m<=10000;
对于100%的数据,1<=n<=10000,1<=m<=100000,1<=a, b<=n, 1<=t<=100000。
2 解决方案
说一下此题题意的理解问题:首先,我要吐槽一下,出题人的语文应该是体育老师教的吧。
原题描述:
现在C国的国王已经知道了每座桥能使用的天数,超过这个天数就不能使用了。现在他想知道居民们会有多少天进行抗议。
输出格式
输出一个整数,表示居民们会抗议的天数。
看到上面描述,外加题目所给实例输入及输出语句,且要确保每个岛屿都能两两到达
,第一印象就是使用最小生成树Kruskal算法。但是,这里要把边的权值变成负值,相应的最小就是该桥能够使用的天数最长,如此再求得最小生成树中的权值绝对值最小的边,即为居民开始进行抗议的天数。
带着这样的思考方式,提交后只得了10分,还是碰巧对的。
带着疑惑心里,看了一些网友的解答,又把题目读了一遍,提取关键点:居民们会抗议的天数,注意是天数,为此我理解为最小生成树中最大权值和最小权值差的绝对值就是答案。但是,网上相关网友的解答都不是这样计算的。
直到,我看到了文末参考资料一篇网友把题目描述修改了一部分,具体如下:
修改后:
现在C国的国王已经知道了每座桥能使用的天数,超过这个天数就不能使用了。现在他想知道居民们一共会发起多少次抗议。
输出
输出一个整数,表示居民们发起抗议的次数。
把这个天字改为次字,即求取最小生成树中权值不同的个数即为最终所求答案。为此,本题下面先求取最小生成树,然后用HashSet存放权值,最终set集合中元素个数即为最终答案。
下面代码在蓝桥系统中运行超时,具体原因应该是Java语言和C++语言编译运行的性能有关,大部分网友C++写的解答都是使用并查算法,其实Kruskal算法的本质也是并查算法,我用网友C++代码跑的是100分。

具体代码如下:
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Scanner; public class Main {
public static int n, m;
public static int[] id;
public static ArrayList<edge> list = new ArrayList<edge>();
public static HashSet<Integer> set = new HashSet<Integer>(); class MyComparator implements Comparator<edge> {
public int compare(edge arg0, edge arg1) {
if(arg0.t > arg1.t)
return 1;
else if(arg0.t < arg1.t)
return -1;
return 0;
}
} static class edge {
public int a;
public int b;
public int t; public edge(int a, int b, int t) {
this.a = a;
this.b = b;
this.t = t;
}
} public int find(int a) {
int root = a;
while(id[root] >= 0) {
root = id[root];
}
int i = 0, k = a;
while(k != root) {
i = id[k];
id[k] = root;
k = i;
}
return root;
} public void union(int a, int b) {
int rootA = find(a);
int rootB = find(b);
if(rootA == rootB)
return;
int num = id[rootA] + id[rootB];
if(id[rootA] < id[rootB]) {
id[rootB] = rootA;
id[rootA] = num;
} else {
id[rootA] = rootB;
id[rootB] = num;
}
} public void kruskal() {
Collections.sort(list, new MyComparator());
id = new int[n + 1];
for(int i = 1;i <= n;i++)
id[i] = -1;
int count = 0;
for(int i = 0;i < list.size();i++) {
edge p = list.get(i);
if(find(p.a) != find(p.b)) {
set.add(p.t);
union(p.a, p.b);
count++;
if(count == n - 1)
break;
}
}
System.out.println(set.size());
} public static void main(String[] args) {
Main test = new Main();
Scanner in = new Scanner(System.in);
n = in.nextInt();
m = in.nextInt();
for(int i = 0;i < m;i++) {
int a = in.nextInt();
int b = in.nextInt();
int t = in.nextInt();
list.add(new edge(a, b, -1 * t));
}
test.kruskal();
}
}
参考资料:
算法笔记_180:历届试题 国王的烦恼(Java)的更多相关文章
- 算法笔记_174:历届试题 地宫取宝(Java)
目录 1 问题描述 2 解决方案 1 问题描述 问题描述 X 国王有一个地宫宝库.是 n x m 个格子的矩阵.每个格子放一件宝贝.每个宝贝贴着价值标签. 地宫的入口在左上角,出口在右下角. 小明 ...
- 算法笔记_189:历届试题 横向打印二叉树(Java)
目录 1 问题描述 2 解决方案 1 问题描述 问题描述 二叉树可以用于排序.其原理很简单:对于一个排序二叉树添加新节点时,先与根节点比较,若小则交给左子树继续处理,否则交给右子树. 当遇到空子树 ...
- 算法笔记_176:历届试题 最大子阵(Java)
目录 1 问题描述 2 解决方案 1 问题描述 问题描述 给定一个n*m的矩阵A,求A中的一个非空子矩阵,使这个子矩阵中的元素和最大. 其中,A的子矩阵指在A中行和列均连续的一块. 输入格式 输入 ...
- 算法笔记_198:历届试题 打印十字图(Java)
目录 1 问题描述 2 解决方案 1 问题描述 问题描述 小明为某机构设计了一个十字型的徽标(并非红十字会啊),如下所示: ..$$$$$$$$$$$$$....$...........$..$$ ...
- 算法笔记_191:历届试题 大臣的旅费(Java)
目录 1 问题描述 2 解决方案 1 问题描述 问题描述 很久以前,T王国空前繁荣.为了更好地管理国家,王国修建了大量的快速路,用于连接首都和王国内的各大城市. 为节省经费,T国的大臣们经过思考, ...
- 算法笔记_185:历届试题 格子刷油漆(Java)
目录 1 问题描述 2 解决方案 1 问题描述 问题描述 X国的一段古城墙的顶端可以看成 2*N个格子组成的矩形(如下图所示),现需要把这些格子刷上保护漆. 你可以从任意一个格子刷起,刷完一格,可 ...
- 算法笔记_182:历届试题 核桃的数量(Java)
目录 1 问题描述 2 解决方案 1 问题描述 问题描述 小张是软件项目经理,他带领3个开发组.工期紧,今天都在加班呢.为鼓舞士气,小张打算给每个组发一袋核桃(据传言能补脑).他的要求是: 1. ...
- 算法笔记_181:历届试题 回文数字(Java)
目录 1 问题描述 2 解决方案 1 问题描述 问题描述 观察数字:12321,123321 都有一个共同的特征,无论从左到右读还是从右向左读,都是相同的.这样的数字叫做:回文数字. 本题要求你找 ...
- 算法笔记_169:历届试题 兰顿蚂蚁(Java)
目录 1 问题描述 2 解决方案 1 问题描述 问题描述 兰顿蚂蚁,是于1986年,由克里斯·兰顿提出来的,属于细胞自动机的一种. 平面上的正方形格子被填上黑色或白色.在其中一格正方形内有一只“蚂 ...
随机推荐
- 图解vim常用命令
VI 即 Visual Interface,可视化接口,VIM是VI的增强版 (improved),两张图总结vim常用命令. 图片来自 https://www.cnblogs.com/yangjig ...
- linux下TP5安装好Workerman 报错:Class 'think\worker\Server' not found
今天把功能放到服务器,本地测试正常,上传到服务器上报错Class 'think\worker\Server' not found 首先想到的是Windows和Linux下大小写的问题,查看了代码,并没 ...
- fragment和fragmentactivity解析
一.为什么要使用Fragment 1.当我们须要动态的多界面切换的时候,就须要将UI元素和Activity融合成一个模块.在2.3中我们一般通过各种Activity中进行跳转来实现多界面的跳转和单个 ...
- 用swift开发仪表盘控件(一)
苹果swift刚刚推出不久,接触到这个语言是一个偶然的机会,无聊之余随便看了下它的语法: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveW5tYW95b2 ...
- golang 字符串与整数, 布尔转换 strconv
strconv 是golang对于字符串和基本数据类型之间的转换字符串转整数testStr := "1000" testInt, err := strconv.Atoi(testS ...
- 《STL源代码剖析》---stl_set.h阅读笔记
SET是STL中的标准容器,SET里面的元素会依据键值自己主动排序,它不像map那样拥有实值value和键值key的相应,set仅仅有实值.SET的底层实现时RB-tree,当插入到RB-tree中后 ...
- 纯html上下翻滚效果公告板
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- Windows和Linux下如何查看端口被哪个进程占用
Windows: C:/Users/ewanbao>netstat -aon|findstr "123" TCP 127.0.0.1:55123 0.0 ...
- Common Internet File System
CIFS (Common Internet File System) is a protocol that gained popularity around the year 2000, as ven ...
- python文章学习列表
1.https://home.cnblogs.com/u/darkpig/feed/blog/ 这篇博主的系列文章 2.