算法笔记_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年,由克里斯·兰顿提出来的,属于细胞自动机的一种. 平面上的正方形格子被填上黑色或白色.在其中一格正方形内有一只“蚂 ...
随机推荐
- LAMP架构之NFS
需求分析: 前端需支持更大的访问量,单台Web服务器已无法满足需求了,则需扩容Web服务器: 虽然动态内容可交由后端的PHP服务器执行,但静态页面还需要Web服务器自己解析,那是否意味着多台Web服务 ...
- InvalidateRect(转)
///===================该段是自己总结的一个小结================================= InvalidateRect()函数的作用是设置一个无效区域,并 ...
- Zookeeper Monitor集群监控开发
随着线上越来越多的系统依赖Zookeeper集群.以至于Zookeeper集群的执行状况越来越重要.可是眼下还没有什么好用的Zookeeper集群监控系统(淘宝开源了一个Zookeeper监控系统,可 ...
- AES advanced encryption standard
// advanced encryption standard // author: karl malbrain, malbrain@yahoo.com typedef unsigned char u ...
- redhat 对应LINUX 内核版本是多少
http://blog.chinaunix.net/uid-12798245-id-4743373.html
- [c#]WebClient异步下载文件并显示进度
摘要 在项目开发中经常会用到下载文件,这里使用winform实现了一个带进度条的例子. 一个例子 using System; using System.Collections.Generic; usi ...
- 使用Facade模式更新库存、确认订单、采取打折、确认支付、完成支付、物流配送
Facade模式对外提供了统一的接口,而隐藏了内部细节.在网上购物的场景中,当点击提交订单按钮,与此订单相关的库存.订单确认.折扣.确认支付.完成支付.物流配送等都要做相应的动作.本篇尝试使用Faca ...
- andriod 错误:Only the original thread that created a view hierarchy can touch its views——Handler的使用
package com.example.yanlei.myapplication; import android.media.MediaMetadataRetriever; import androi ...
- Extjs NumberField 开始值 不能大于 结束值
Ext.apply(Ext.form.VTypes,{ numberrange: function(val, field) { var num = parseFloat(val); if (field ...
- SQL游标、函数的使用方法
游标的的使用有日常的开发和维护的过程不使用的并不多,但是碰到一些棘手的问题的时候,游标时常是个非常好的帮手,下面就说下游标的使用方法,方法自己以后查阅,和加深一些印象,下面以一个存储过程为例 ...