UVa 1151 买还是建
https://vjudge.net/problem/UVA-1151
题意:
平面上有n个点,你的任务是让所有n个点连通。为此,你可以新建一些边,费用等于两个端点的距离平方和。另外还有q个套餐可以购买,如果你购买了第i个套餐,该套餐中的所有结点都变得相互连通,第i个套餐的花费为Ci。
思路:
这道题比较容易超时。可能需要用到并查集的路径压缩,我下面的代码就是用了路径压缩,不然要超时。也是看了别人的代码才知道还有这种省时间的做法。
先介绍一下路径压缩吧:

如果并查集像一字长蛇这样排列的话,寻找起来就比较费时间,但如果像图2一样的话,一下子就可以找到根了。压缩的方法也是挺简单的。
int r = x;
while (r != p[r]) r = p[r];
int i = x, j;
while (p[i] != r)
{
j = p[i];
p[i] = r;
i = j;
}
题目的做法就像紫书上说的那样,先不考虑套餐算一遍,然后枚举套餐的方法,这里的话二进制枚举法非常方便。
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std; const int maxn = + ; int n, m, q, cnt;
int p[maxn];
vector<int> g[]; //方案集合
int c[]; //方案价格 //边
struct node
{
int u;
int v;
int dist;
}edge[maxn*maxn]; //点
struct node2
{
int x, y;
}a[maxn]; int find(int x)
{
//return p[x] == x ? x : find(p[x]); 用这个会超时
//路径压缩
int r = x;
while (r != p[r]) r = p[r];
int i = x, j;
while (p[i] != r)
{
j = p[i];
p[i] = r;
i = j;
}
return r;
} bool cmp(node a, node b)
{
return a.dist < b.dist;
} //计算距离平方和
int cacl_dist(node2 a, node2 b)
{
return (a.x - b.x)*(a.x - b.x) + (a.y - b.y)*(a.y - b.y);
} void init()
{
for (int k = ; k <= n; k++) p[k] = k;
} int Kruskal()
{
int num = ;
int ans = ;
for (int i = ; i < cnt ; i++)
{
int x = find(edge[i].u);
int y = find(edge[i].v);
if (x != y)
{
p[x] = y;
ans += edge[i].dist;
num++;
}
if (num == n - ) return ans;
}
return ans;
} void solve()
{
init();
int ans = Kruskal();
//二进制枚举方案
for (int i = ; i < ( << q); i++)
{
init();
int cost = ;
for (int j = ; j < q; j++)
{
if (i & ( << j))
{
cost += c[j];
int x = find(g[j][]);
for (int k = ; k < g[j].size(); k++)
{
int y = find(g[j][k]);
if (x != y)
p[y] = x;
}
}
}
ans = min(cost + Kruskal(), ans);
}
printf("%d\n", ans);
} int main()
{
//freopen("D:\\txt.txt", "r", stdin);
int T, t, s, kase=;
scanf("%d", &T);
while (T--)
{
if (++kase > ) printf("\n");
scanf("%d%d", &n, &q); //存储方案
for (int i = ; i < q; i++)
{
g[i].clear();
scanf("%d", &t);
scanf("%d", &c[i]);
for (int j = ; j < t; j++)
{
scanf("%d", &s);
g[i].push_back(s);
}
} for (int i = ; i <= n; i++)
scanf("%d%d", &a[i].x, &a[i].y); //存储边
cnt = ;
for (int i = ; i <= n;i++)
for (int j = i + ; j <= n; j++)
{
edge[cnt].u = i;
edge[cnt].v = j;
edge[cnt].dist = cacl_dist(a[i], a[j]);
cnt++;
}
sort(edge, edge + cnt, cmp);
solve();
}
return ;
}
UVa 1151 买还是建的更多相关文章
- UVA 1151 买还是建(最小生成树)
买还是建 紫书P358 [题目链接]买还是建 [题目类型]最小生成树 &题解: 这题真的心累,看了3天,最后照着码还是wa,先放lrj代码,以后再看吧 &代码: // UVa1151 ...
- UVA - 1151 Buy or Build (买还是建)(并查集+二进制枚举子集)
题意:平面上有n个点(1<=n<=1000),你的任务是让所有n个点连通.可以新建边,费用等于两端点欧几里德距离的平方.也可以购买套餐(套餐中的点全部连通).问最小费用. 分析: 1.先将 ...
- 洛谷 题解 UVA1151 【买还是建 Buy or Build】
[题意] 平面上有\(n(n<=1000)\)个点,你的任务是让所有n个点联通.为此,你可以新建一些边,费用等于两个端点的欧几里得距离平方.另外还有\(q(q<=8)\)个套餐可以购买,如 ...
- UVa 1151 - Buy or Build(最小生成树)
链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...
- UVA 1151
/* 题意:有n个点,现在需要联通所有,有q种套餐可以选择, 当然套餐之外也可以自己添加边,意为达到最短距离. 题意很明显,不知道需要使用哪一种套餐, 那么需要枚举每一种套餐的情况. 然后再进行对比. ...
- uva 1151(最小生成树,枚举子集)
题意:平面上有n个点(1<=N<=1000),你的任务是让所有n个点连通,为此,你可以新建一些边,费用等于两个端点的欧几里得距离的平方.另外还有q(0<=q<=8)个套餐,可以 ...
- UVA 1151 Buy or Build (MST最小生成树,kruscal,变形)
题意: 要使n个点之间能够互通,要使两点直接互通需要耗费它们之间的欧几里得距离的平方大小的花费,这说明每两个点都可以使其互通.接着有q个套餐可以选,一旦选了这些套餐,他们所包含的点自动就连起来了,所需 ...
- UVa 1151 (枚举 + MST) Buy or Build
题意: 平面上有n个点,现在要把它们全部连通起来.现在有q个套餐,如果购买了第i个套餐,则这个套餐中的点全部连通起来.也可以自己单独地建一条边,费用为两点欧几里得距离的平方.求使所有点连通的最小费用. ...
- UVa 1151 Buy or Build (最小生成树+二进制法暴力求解)
题意:给定n个点,你的任务是让它们都连通.你可以新建一些边,费用等于两点距离的平方(当然越小越好),另外还有几种“套餐”,可以购买,你购买的话,那么有些边就可以连接起来, 每个“套餐”,也是要花费的, ...
随机推荐
- 流媒体ts/ps流封装/分析
1.TS 1) 感谢星辰同学,还热乎着,
- 让你分分钟了解Web接口测试
因为前后端架构分离技术的兴起,接口测试也越来越重要,最近一直想总结下,作为一个近三年的测试人员,接口这个词是耳濡目染的,而开发张口闭口也都是这个接口或那个接口怎么怎么样,自己遇到的bug也很多是接口问 ...
- Py-apply用法学习【转载】
转自:https://blog.csdn.net/anshuai_aw1/article/details/82347016 1.Apply Python中apply函数的格式为:apply(func, ...
- 容器集成平台 rancher部署
下载rancher镜像 docker pull rancher/server:stable rancher/server:latest #开发版 rancher/server:stable #稳定版 ...
- 批量生成反色图片,用PHOTOSHOP批处理功能。
http://zhidao.baidu.com/link?url=Iz46PDPnEITummTEwo2GtUrK6AeAjlidJ7HtCPJ6NYZJbbllRwNg2iBAcNwF2TYjccP ...
- XenServer:使用XenCenter开设VPS(多图完整版)
打铁要趁热,咱们接着来玩XenServer.昨天赵容用机房提供的KVM给服务器装了XenServer,今天我们来玩更有意思的:开小鸡.装好XenServer之后,访问我们的服务器IP,就可以看到Xen ...
- 深度学习Momentum(动量方法)
转自:http://blog.csdn.net/bvl10101111/article/details/72615621 先上结论: 1.动量方法主要是为了解决Hessian矩阵病态条件问题(直观上讲 ...
- MySQL用户授权 和 bin-log日志 详解和实战(http://www.cnblogs.com/it-cen/p/5234345.html)
看 了上一篇博文的发布时间,到目前已经有三个月没更新博文了.这三个月经历了很多事情,包括工作.生活和感情等等.由于个人发展的原因,这个月准备换工作 啦.在这段时间,我会把Web大型项目中所接触到的技术 ...
- AO中的空间关系
名词解释: Boundary(边界): 只有线和面才有边界.面的边界是指组成面的框架线:线的边界是指线的二个端点(即起点和终点,不包括中间部分的节点):点没有边界. Interior(内部): 除去边 ...
- HexDump.java解析,android 16进制转换
HexDump.java解析android 16进制转换 package com.android.internal.util; public class HexDump { private final ...