BZOJ 1083: [SCOI2005]繁忙的都市【Kruscal最小生成树裸题】
1083: [SCOI2005]繁忙的都市
Time Limit: 10 Sec Memory Limit: 162 MB
Submit: 2925 Solved: 1927
Description
城市C是一个非常繁忙的大都市,城市中的道路十分的拥挤,于是市长决定对其中的道路进行改造。城市C的道 路是这样分布的:城市中有n个交叉路口,有些交叉路口之间有道路相连,两个交叉路口之间最多有一条道路相连 接。这些道路是双向的,且把所有的交叉路口直接或间接的连接起来了。每条道路都有一个分值,分值越小表示这 个道路越繁忙,越需要进行改造。但是市政府的资金有限,市长希望进行改造的道路越少越好,于是他提出下面的 要求: 1. 改造的那些道路能够把所有的交叉路口直接或间接的连通起来。 2. 在满足要求1的情况下,改造的 道路尽量少。 3. 在满足要求1、2的情况下,改造的那些道路中分值最大的道路分值尽量小。任务:作为市规划 局的你,应当作出最佳的决策,选择那些道路应当被修建。
Input
第一行有两个整数n,m表示城市有n个交叉路口,m条道路。接下来m行是对每条道路的描述,u, v, c表示交叉 路口u和v之间有道路相连,分值为c。(1≤n≤300,1≤c≤10000)
Output
两个整数s, max,表示你选出了几条道路,分值最大的那条道路的分值是多少。
Sample Input
4 5 1 2 3 1 4 5 2 4 7 2 3 6 3 4 8
Sample Output
3 6
HINT
Source
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1083
题意 给定一张图,求其最小生成树中权值最大的边
要是学习过最小生成树的相关概念,就会发现这道题就是直接考察的最小生成树,只不过题目没有问你最小生成树的边权和,而是让你输出最小生成树有几条边(点数-1)和权值最大的那条边的权值。
那么什么是生成树呢?
In the mathematical field of graph theory, a spanning tree T of an undirected graph G is a subgraph that is a tree which includes all of the vertices of G. In general, a graph may have several spanning trees, but a graph that is not connected will not contain a spanning tree (but see Spanning forests below). If all of the edges of G are also edges of a spanning tree T of G, then G is a tree and is identical to T (that is, a tree has a unique spanning tree and it is itself).
Paste_Image.png
如上图所示,生成树就是在给定的图中选取最少的边使所有顶点连通,那么最小生成树就是选取的边的权值和最小。
了解了生成树的概念,就很容易能明白生成树只有n-1条边,其中n表示顶点数。 那么怎么求最小生成树呢? 这里我介绍kruscal算法。
克鲁斯卡尔算法 该算法用到的是贪心思想,将所有的边按权值排序,每次都选权值最小的边,然后判断这条边的两个顶点是否属于同一个连通块,如果不属于同一个连通块,那么这条边就应属于最小生成树,逐渐进行下去,直到连通块只剩下一个。
kruscal算法的模板代码如下:
1 const int maxn=400;//最大点数
2 const int maxm=10000;//最大边数
3 int n,m;//n表示点数,m表示边数
4 struct edge{int u,v,w;} e[maxm];//u,v,w分别表示该边的两个顶点和权值
5 bool cmp(edge a,edge b)
6 {
7 return a.w<b.w;
8 }
9 int fa[maxn];//因为需要用到并查集来判断两个顶点是否属于同一个连通块
10 int find(int x)
11 {
12 if(x==fa[x]) return x;
13 else return fa[x]=find(fa[x]);
14 }
15 int kruscal()
16 {
17 int ans=-1;
18 sort(e+1,e+1+m,cmp);
19 for(int i=1;i<=n;++i) fa[i]=i;//初始化并查集
20 int cnt=n;
21 for(int i=1;i<=m;++i)
22 {
23 int t1=find(e[i].u);
24 int t2=find(e[i].v);
25 if(t1!=t2)
26 {
27 if(cnt==1) break;
28 fa[t1]=t2;
29 ans=max(ans,e[i].w);
30 cnt--;
31 }
32 }
33 return ans;
34 }
针对这道题,我们只需要把ans+=e[i].w改为ans=max(ans,e[i].w)就好了,至此问题得到了解决。
1 #include <bits/stdc++.h>
2 using namespace std;
3 const int maxn=400;///最大点数
4 const int maxm=10000;///最大边数
5 int n,m;///n表示点数,m表示边数
6 struct edge
7 {
8 int u,v,w;///u,v,w分别表示该边的两个顶点和权值
9 }e[maxm];
10 bool cmp(edge a,edge b)
11 {
12 return a.w<b.w;
13 }
14 int fa[maxn];///判断两个点是否属于同一个连通块
15 int find(int x)
16 {
17 if(x==fa[x])
18 return x;
19 else return fa[x]=find(fa[x]);
20 }
21 int kruscal()
22 {
23 int ans=-1;
24 sort(e+1,e+1+m,cmp);
25 for(int i=1;i<=n;i++)
26 fa[i]=i;///初始化并查集
27 int cnt=n;
28 for(int i=1;i<=m;i++)
29 {
30 int t1=find(e[i].u);
31 int t2=find(e[i].v);
32 if(t1!=t2)
33 {
34 if(cnt==1)
35 break;
36 fa[t1]=t2;
37 ///ans+=e[i].w;
38 ans=max(ans,e[i].w);
39 cnt--;
40 }
41 }
42 return ans;
43 }
44 int main()
45 {
46 cin>>n>>m;
47 for(int i=1;i<=m;i++)
48 {
49 cin>>e[i].u>>e[i].v>>e[i].w;
50 }
51 cout<<n-1<<" ";
52 cout<<kruscal()<<endl;
53 return 0;
54 }
- Python 项目实践一(外星人入侵小游戏)第二篇
- IBatisNet配置
- WordPress设置评论到达一定数量后自动关闭评论功能
- Python 项目实践一(外星人入侵)第一篇
- 外媒:域名Covermate.com超35万终端交易
- 移除WordPress 管理后台的主题编辑功能
- 百度区域链开放平台“BaaS”启用了二级子域名chain.baidu.com
- Qt界面UI之QML初见(学习笔记四)
- 清新唯美的jQuery天气预报插件(网页天气预报插件)
- 32和64位的CentOS 6.0下 安装 Mono 2.10.8 和Jexus 5.0
- 跨平台的 .NET 运行环境 Mono 3.2 新特性
- Ibatisnet Quick Start
- 常见的3种Hive参数配置方法
- 6杂域名超16万元结拍
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- java设计模式-单例模式
- Spring事务专题(三)事务的基本概念,Mysql事务处理原理
- cocos creator使用protobuf实现网络模块
- 简单聊聊红黑树(Red Black Tree)
- cocos creator探照灯效果实现
- servlet/filter/listener/interceptor区别与联系
- Linux下文本的简单处理(awk和sed)
- Spring4定时器 cronTrigger和simpleTrigger实现方法
- Tomcat远程调试
- IDEA建立Spring MVC Hello World 详细入门教程
- 嗯,手搓一个TinyPng压缩图片的WebpackPlugin也SoEasy啦
- Spring源码解析——核心类介绍
- IO之Basic IO
- 静态方法中注入bean
- 高通量数据中批次效应的鉴定和处理(五)- 预测并校正可能存在的混杂因素