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 ...
随机推荐
- Java 8 Optional类深度解析
身为一名Java程序员,大家可能都有这样的经历:调用一个方法得到了返回值却不能直接将返回值作为参数去调用别的方法.我们首先要判断这个返回值是否为null,只有在非空的前提下才能将其作为其他方法的参数. ...
- acpi和btrfs-安装opensuse时的选项
g-------------------- 关于GPL和LGPL和QPL等 读书笔记:采用LGPL的代码,一般情况下它本身就是一个第三方库(别忘了LGPL最早的名字就是Library GPL),这时候 ...
- C#集合u
List<T> 列表(动态数组),相当于C++的 vector Queue<T> 队列,先进先出 Stack<T> 栈,先进后出 LinkedList<T&g ...
- 关于使用jacob出现的异常
1) 把jacob.jar加载到工程里:2) 把jacob.dll放入 JAVA_HOME\bin\ 和 JAVA_HOME\jre\bin目录下:3) 把jacob.dll放入 C:\WINDOW ...
- jQuery源码-dom操作之jQuery.fn.html
写在前面 前面陆陆续续写了jQuery源码的一些分析,尽可能地想要cover里面的源码细节,结果导致进度有些缓慢.jQuery的源码本来就比较晦涩,里面还有很多为了解决兼容问题很引入的神代码,如果不g ...
- 那些你不知道的chrome URLs
Xee:我用的是七星浏览器,因为我看了很多的浏览器,它们的版本都停滞不前了: 360安全浏览器的重度用户肯定不会对 se:last (上次未关闭页面)这个页面感到陌生,即使您没有见过这个,但也一定很熟 ...
- SGU 495. Kids and Prizes
水概率....SGU里难得的水题.... 495. Kids and Prizes Time limit per test: 0.5 second(s)Memory limit: 262144 kil ...
- Ubuntu 14 安装并破解SSH工具 SecureCRT
[安装篇] 1.到官网下载:SecureCRT.839.ubuntu13-64.tar.gz https://www.vandyke.com/download/securecrt/download.h ...
- php正则
PHP代码 $str = preg_replace("/(<a.*?>)(.*?)(<\/a>)/", '\1<span class="li ...
- Mac os装软件时提示显示需要安装旧Java SE 6运行环境解决办法
这个时Java版本的问题,换用合适的低版本即可,下面是官方的 https://support.apple.com/kb/DL1572?viewlocale=zh_CN&locale=en_US ...