ACM/ICPC 之 四道MST-Kruskal解法-练习题(POJ1251-POJ1287-POJ2031-POJ2421)
由于题目简单,部分题意写在代码中(简单题就应该多练英文...),且较少给注释,需要注意的地方会写在代码中,虽然四个题意各有千秋,但万变不离其宗,细细思考一番会发现四道题都属于很直接的最小生成树问题,由于博主时间原因,暂提供Kruskal解法。
这四题可以作为最小生成树(MST)入门的上手题库。
POJ1251(ZOJ1406)-Jungle Roads
//Kruskal-裸
//POJ1251-ZOJ1406
//找出维护道路的最小费用
//Time:0Ms Memory:168K
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std; #define MAXN 28
#define MAXM 80 struct Edge {
int u, v;
int d;
friend bool operator < (Edge e1, Edge e2) { return e1.d < e2.d; }
}e[MAXM]; int n, m;
int fa[MAXN]; int Find(int x)
{
return fa[x] < ? x : fa[x] = Find(fa[x]);
} void Union(int r1,int r2)
{
int num = fa[r1] + fa[r2];
if (r1 < r2)
{
fa[r2] = r1;
fa[r1] = num;
}
else {
fa[r1] = r2;
fa[r2] = num;
}
} void kruskal()
{
int num = ;
int minroad = ;
memset(fa, -, sizeof(fa));
for (int i = ; i < m; i++)
{
int r1 = Find(e[i].u);
int r2 = Find(e[i].v);
if (r1 == r2) continue;
minroad += e[i].d;
Union(r1, r2);
if (++num == n - ) break;
}
printf("%d\n", minroad);
} int main()
{
while (scanf("%d", &n), n)
{
m = ;
for (int i = ; i < n; i++)
{
int road;
char city[];
scanf("%s%d", city, &road); //用%c和getchar()会RE,可能是后台数据的问题
while (road--)
{
int d;
char c[];
scanf("%s%d", c, &d);
e[m].u = city[] - 'A';
e[m].v = c[] - 'A';
e[m++].d = d;
}
}
sort(e, e + m);
kruskal();
}
return ;
}
POJ1287(ZOJ1372)-Networking
//Kruskal-须查重边
//设计一个由给定所需网线长度的网络组成的最短网线方案(可能有重边)
//POJ1287-ZOJ1372
//Time:16Ms Memory:192K
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std; #define MAXN 51 struct Edge {
int u, v;
int d;
friend bool operator < (Edge e1, Edge e2) { return e1.d < e2.d; }
}e[MAXN*MAXN]; int n, m;
int fa[MAXN];
int v[MAXN][MAXN]; //端点查边
int minroad; int Find(int x)
{
return fa[x] < ? x : fa[x] = Find(fa[x]);
} void Union(int r1, int r2)
{
int num = fa[r1] + fa[r2];
if (r1 < r2)
{
fa[r2] = r1;
fa[r1] = num;
}
else {
fa[r1] = r2;
fa[r2] = num;
}
} void kruskal()
{
int num = ;
minroad = ;
memset(fa, -, sizeof(fa));
for (int i = ; i < m; i++)
{
int r1 = Find(e[i].u);
int r2 = Find(e[i].v);
if (r1 == r2) continue;
Union(r1, r2);
minroad += e[i].d;
if (++num == n - ) break;
}
printf("%d\n", minroad);
} int main()
{
while (scanf("%d", &n), n)
{
memset(v, -, sizeof(v));
scanf("%d", &m);
for (int i = ; i < m; i++)
{
scanf("%d%d%d", &e[i].u, &e[i].v, &e[i].d);
if (v[e[i].u][e[i].v] >= ) //查重
{
e[v[e[i].u][e[i].v]].d = min(e[v[e[i].u][e[i].v]].d, e[i].d);
i--; m--;
}
else v[e[i].u][e[i].v] = i;
}
sort(e, e + m);
kruskal();
}
return ;
}
POJ2031(ZOJ1718)-Jungle Roads
//Kruskal+去重叠+简单几何
//题目不难,如果用到并查集,那么去重的部分需要考虑好
//Time:32Ms Memory:268K
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std; #define MAXN 105
#define POW2(x) ((x)*(x))
#define DIS(i,j) (sqrt(POW2(v[i].x - v[j].x) + POW2(v[i].y - v[j].y) + POW2(v[i].z - v[j].z))) struct Vertex {
double x, y, z;
double r;
}v[MAXN]; struct Edge {
int u, v;
double d;
friend bool operator < (Edge e1, Edge e2) { return e1.d < e2.d; }
}e[MAXN*MAXN]; int n, m;
int fa[MAXN]; int Find(int x)
{
return fa[x] < ? x : fa[x] = Find(fa[x]);
} void Union(int r1, int r2)
{
r1 = Find(r1);
r2 = Find(r2);
if (r1 == r2) return; //处理边的时候需要考虑,否则将RE
int num = fa[r1] + fa[r2];
if (r1 < r2)
{
fa[r2] = r1;
fa[r1] = num;
}
else {
fa[r1] = r2;
fa[r2] = num;
}
} void kruskal()
{
int num = ;
double minroad = ;
for (int i = ; i < m; i++)
{
int r1 = Find(e[i].u);
int r2 = Find(e[i].v);
if (r1 == r2) continue;
Union(r1, r2);
minroad += e[i].d;
if (++num == n - ) break;
}
printf("%.3lf\n", minroad);
} int main()
{
while (scanf("%d", &n), n)
{
m = ;
memset(fa, -, sizeof(fa));
for (int i = ; i < n; i++)
{
scanf("%lf%lf%lf%lf", &v[i].x, &v[i].y, &v[i].z, &v[i].r);
for (int j = ; j < i; j++)
{
double len = DIS(i, j) - v[i].r - v[j].r;
if (len <= 1e-)
Union(i, j); //可能r1与r2同集合-在Union中处理
else {
e[m].u = i;
e[m].v = j;
e[m++].d = len;
}
}
}
sort(e, e + m);
kruskal();
}
return ;
}
POJ2421-Jungle Roads
//Kruskal-略变形
//Time:47Ms Memory:272K
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
#define MAX 105 struct Edge {
int u, v;
int d;
friend bool operator < (Edge e1, Edge e2) { return e1.d < e2.d; }
}e[MAX*MAX/]; int n, m;
int fa[MAX];
int d[MAX][MAX]; int Find(int x)
{
return fa[x] < ? x : fa[x] = Find(fa[x]);
} void Union(int r1, int r2)
{
r1 = Find(r1);
r2 = Find(r2);
if (r1 == r2) return;
int num = fa[r1] + fa[r2];
if (fa[r1] < fa[r2])
{
fa[r2] = r1;
fa[r1] = num;
}
else {
fa[r1] = r2;
fa[r2] = num;
}
} void kruskal()
{
int minroad = ;
int num = ;
for (int i = ; i < m; i++)
{
int r1 = Find(e[i].u);
int r2 = Find(e[i].v);
if (r1 == r2) continue;
Union(r1, r2);
minroad += e[i].d;
if (++num == n - ) break;
}
printf("%d\n", minroad);
} int main()
{
memset(fa, -, sizeof(fa));
scanf("%d", &n);
for (int i = ; i <= n; i++)
for (int j = ; j <= n; j++)
scanf("%d", &d[i][j]);
int k;
scanf("%d", &k);
while (k--)
{
int u, v;
scanf("%d%d", &u, &v);
Union(u, v);
}
m = ;
for (int i = ; i <= n; i++)
for (int j = ; j < i; j++)
{
e[m].u = i;
e[m].v = j;
e[m++].d = d[i][j];
}
sort(e, e + m);
kruskal();
return ;
}
ACM/ICPC 之 四道MST-Kruskal解法-练习题(POJ1251-POJ1287-POJ2031-POJ2421)的更多相关文章
- ACM/ICPC 之 四道MST-Prim解法(POJ1258-POJ1751-POJ2349-POJ3026)
四道MST,适合Prim解法,也可以作为MST练习题. 题意包括在代码中. POJ1258-Agri Net 水题 //Prim-没什么好说的 //接受一个邻接矩阵,求MST //Time:0Ms M ...
- ACM/ICPC 之 判别MST唯一性-Kruskal解法(POJ1679)
判别MST是否唯一的例题. POJ1679-The Unique MST 题意:给定图,求MST(最小生成树)是否唯一,唯一输出路径长,否则输出Not Unique! 题解:MST是否唯一取决于是否有 ...
- ACM/ICPC 之 Kruskal范例(ZOJ1203-POJ1861(ZOJ1542))
两道最小生成树范例,Kruskal解法-以边为主体扩展最小生成树,需要利用并查集. ZOJ1203-Swordfish 题意:求n个给定平面坐标的城市中的一条平面距离上的最短路长(保留两位小数) 题解 ...
- 【转】lonekight@xmu·ACM/ICPC 回忆录
转自:http://hi.baidu.com/ordeder/item/2a342a7fe7cb9e336dc37c89 2009年09月06日 星期日 21:55 初识ACM最早听说ACM/ICPC ...
- ACM/ICPC 之 Prim范例(ZOJ1586-POJ1789(ZOJ2158))
两道Prim解法范例题型,简单的裸Prim,且两题相较以边为重心的Kruskal解法而言更适合以点为重心扩展的Prim解法. ZOJ1586-QS Network 题意:见Code 题解:直接的MST ...
- ACM/ICPC 之 BFS(离线)+康拓展开(TSH OJ-玩具(Toy))
祝大家新年快乐,相信在新的一年里一定有我们自己的梦! 这是一个简化的魔板问题,只需输出步骤即可. 玩具(Toy) 描述 ZC神最擅长逻辑推理,一日,他给大家讲述起自己儿时的数字玩具. 该玩具酷似魔方, ...
- 2016 ACM/ICPC Asia Regional Dalian Online 1006 /HDU 5873
Football Games Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)To ...
- 2015 ACM / ICPC 亚洲区域赛总结(长春站&北京站)
队名:Unlimited Code Works(无尽编码) 队员:Wu.Wang.Zhou 先说一下队伍:Wu是大三学长:Wang高中noip省一:我最渣,去年来大学开始学的a+b,参加今年区域赛之 ...
- 2016 ACM/ICPC亚洲区青岛站现场赛(部分题解)
摘要 本文主要列举并求解了2016 ACM/ICPC亚洲区青岛站现场赛的部分真题,着重介绍了各个题目的解题思路,结合详细的AC代码,意在熟悉青岛赛区的出题策略,以备战2018青岛站现场赛. HDU 5 ...
随机推荐
- 性能:15个JavaScript本地存储技术的函数库和工具
当构建更复杂的JavaScript应用程序运行在用户的浏览器是非常有用的,它可以在浏览器中存储信息,这样的信息可以被共享在不同的页面,浏览会话. 在最近的过去,这将有可能只被cookies文本文件保存 ...
- ASP.NET Core -- 安装版
首先安装的→Visual Studio Community 原文地址 本来觉得安装了vs 就可以了,,结果一直报错,,,太天真... 接下来还要安装 →NuGet.Tools.vsix →DotNet ...
- CLGeocoder "Lost connection to geod" #error# when use geocodeAddressString:completionHandler
I got this warning when I tried to get destination using CLGeoCoder and the warning is coming out ...
- 浅谈checkpoint与内存缓存
事务日志存在检查点checkpoint,把内存中脏数据库写入磁盘,以减少故障恢复的时间,在此之前有必要提下SQL Server内存到底存放了哪些数据? SQL Server内存使用 对SQL Serv ...
- 【C语言入门教程】2.9 小结
本章介绍 C 语言的基本组成部分,数据类型.运算符 和 表达式 构成了 C 语言的语法,熟悉和掌握这些信息是学习 C 语言的必经之路.C 语言具备严谨的语法结构,任何细微的差错可导致程序无法通过编译, ...
- MySQL Cluster 配置文件(config.ini)详解
MySQL Cluster 配置文件(config.ini)详解 ################################################################### ...
- Fedora 24最新工作站版本之四大重要改进
导读 2014年,Fedora.next倡议正式开始建立Fedora Linux未来十年的发展规划.从本质上讲,这项规划旨在进一步使Fedora不再只是一套汇聚多种开源产品的通用库(例如Debian) ...
- 移动端压缩并ajax上传图片解决方案
1.需求 做一个前端可压缩并且上传图片到后台的功能 2.使用组件 用到的主要是jq和LocalResizeIMG这2个库 3.使用方法 a.引入脚本文件 <script type='text/j ...
- Java BigDecimal详解
借用<Effactive Java>这本书中的话,float和double类型的主要设计目标是为了科学计算和工程计算.他们执行二进制浮点运算,这是为了在广域数值范围上提供 较为精确的快速近 ...
- c++对象创建带括号与无括号的区别
class Test{public: Test() {} Test(int a) {}} 1.栈上创建对象 1.1 无括号 Test a; // 调用默认构造函数,栈上分配内存创建对象 1.2 有括号 ...