由于题目简单,部分题意写在代码中(简单题就应该多练英文...),且较少给注释,需要注意的地方会写在代码中,虽然四个题意各有千秋,但万变不离其宗,细细思考一番会发现四道题都属于很直接的最小生成树问题,由于博主时间原因,暂提供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)的更多相关文章

  1. ACM/ICPC 之 四道MST-Prim解法(POJ1258-POJ1751-POJ2349-POJ3026)

    四道MST,适合Prim解法,也可以作为MST练习题. 题意包括在代码中. POJ1258-Agri Net 水题 //Prim-没什么好说的 //接受一个邻接矩阵,求MST //Time:0Ms M ...

  2. ACM/ICPC 之 判别MST唯一性-Kruskal解法(POJ1679)

    判别MST是否唯一的例题. POJ1679-The Unique MST 题意:给定图,求MST(最小生成树)是否唯一,唯一输出路径长,否则输出Not Unique! 题解:MST是否唯一取决于是否有 ...

  3. ACM/ICPC 之 Kruskal范例(ZOJ1203-POJ1861(ZOJ1542))

    两道最小生成树范例,Kruskal解法-以边为主体扩展最小生成树,需要利用并查集. ZOJ1203-Swordfish 题意:求n个给定平面坐标的城市中的一条平面距离上的最短路长(保留两位小数) 题解 ...

  4. 【转】lonekight@xmu·ACM/ICPC 回忆录

    转自:http://hi.baidu.com/ordeder/item/2a342a7fe7cb9e336dc37c89 2009年09月06日 星期日 21:55 初识ACM最早听说ACM/ICPC ...

  5. ACM/ICPC 之 Prim范例(ZOJ1586-POJ1789(ZOJ2158))

    两道Prim解法范例题型,简单的裸Prim,且两题相较以边为重心的Kruskal解法而言更适合以点为重心扩展的Prim解法. ZOJ1586-QS Network 题意:见Code 题解:直接的MST ...

  6. ACM/ICPC 之 BFS(离线)+康拓展开(TSH OJ-玩具(Toy))

    祝大家新年快乐,相信在新的一年里一定有我们自己的梦! 这是一个简化的魔板问题,只需输出步骤即可. 玩具(Toy) 描述 ZC神最擅长逻辑推理,一日,他给大家讲述起自己儿时的数字玩具. 该玩具酷似魔方, ...

  7. 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 ...

  8. 2015 ACM / ICPC 亚洲区域赛总结(长春站&北京站)

    队名:Unlimited Code Works(无尽编码)  队员:Wu.Wang.Zhou 先说一下队伍:Wu是大三学长:Wang高中noip省一:我最渣,去年来大学开始学的a+b,参加今年区域赛之 ...

  9. 2016 ACM/ICPC亚洲区青岛站现场赛(部分题解)

    摘要 本文主要列举并求解了2016 ACM/ICPC亚洲区青岛站现场赛的部分真题,着重介绍了各个题目的解题思路,结合详细的AC代码,意在熟悉青岛赛区的出题策略,以备战2018青岛站现场赛. HDU 5 ...

随机推荐

  1. linux静态库的生成与使用(转)

    linux静态库的生成与使用(转) 库是一种软件组件技术,库里面封装了数据和函数. 库的使用可以使程序模块化. Windows系统包括静态链接库(.lib文件)和动态链接库(.dll文件). Linu ...

  2. C# web api返回类型设置为json的两种方法

    web api写api接口时默认返回的是把你的对象序列化后以XML形式返回,那么怎样才能让其返回为json呢,下面就介绍两种方法: 方法一:(改配置法) 找到Global.asax文件,在Applic ...

  3. linux网络:常用命令(一)

    1.ifconfig  可以查看Linux的网卡情况 ifconfig eth0 查看 eth0的信息 给一块网卡设置多个ip地址: ifconfig eth0:0 192.168.1.12 255. ...

  4. 自定义select控件开发

    目的:select下拉框条目太多(上百),当用户选择具体项时会浪费用户很多时间去寻找,因此需要一个搜索框让用户输入关键字来匹配列表,便于用户选择 示例图: 1.html结构 <div class ...

  5. Maven初级学习(三)常用命令

    依赖关系查看 mvn dependency:list #列表形式展示依赖 mvn dependency:tree #层级关系展示依赖 mvn dependency:analyze #依赖分析 声明周期 ...

  6. [译]git rebase

    rebase就是重新定义你分支的起点, 分支上的commit将生成对应的新的commit并放在你指定的新的起点commit后, 分支上的老commit将被删除. rebase就是将你的分支从一个com ...

  7. Python XML解析(转载)

    Python XML解析 什么是XML? XML 指可扩展标记语言(eXtensible Markup Language). 你可以通过本站学习XML教程 XML 被设计用来传输和存储数据. XML是 ...

  8. 【血的教训】玩 Ubuntu 遇到的致命问题(进不了系统)及 解决方案

    [问题1] 按照文章“U盘安装Windows 7 + Ubuntu 14 双系统笔记”在 Windows 7 基础上安装了 Ubuntu 14 系统,实现双系统切换,某一天, 通过如下命令行 sudo ...

  9. Swift2.1 语法指南——协议

    原档: https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programm ...

  10. springmvc之DispatcherServlet

    1.作用:DispatcherServlet是前置控制器,配置在web.xml(因为DispatcherServlet是一个servelet)文件中的.拦截匹配的请求,Servlet拦截匹配规则要自已 ...