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个点,你的任务是让它们都连通.你可以新建一些边,费用等于两点距离的平方(当然越小越好),另外还有几种“套餐”,可以购买,你购买的话,那么有些边就可以连接起来, 每个“套餐”,也是要花费的, ...
随机推荐
- 安插,复制,替换和删除ul中的li
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- pandas.drop/isnull/fillna/astype的用法
删除表中的某一行或者某一列更明智的方法是使用drop,它不改变原有的df中的数据,而是返回另一个dataframe来存放删除后的数据. (1)清理无效数据 df[df.isnull()] #返回的是个 ...
- 几乎考虑到了每个细节的php图片上传
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> < ...
- 面经:Google两轮背靠背
如题,谷歌两轮背靠背电面.两轮都是废话不多说直奔coding,虽然第一轮的中国大哥还是花了一点点时间了解了一下我的背景.毕业时间.research方向.说好的research面呢? 中国大哥出的题: ...
- linux lvs
- 如何提取app软件的apk格式中的字体?
1.下载apk格式的指定app软件: 2.将apk格式的文件名更改为后缀名为zip格式: 3.用winrar解压软件解压,然后就找到其中的ttf格式的字体文件. 举例说明,我想找到airbnb的app ...
- testng使用DataProvider+Excel实现DDT
DDT,即数据驱动测试 Data Driver Test,我曾经记录了一篇关于python的DDT框架(Excel+DDT数据驱动实例),那么java中的DDT是怎么样的呢?在java中,可以用tes ...
- Devenv 命令行开关
Devenv 可用来设置集成开发环境 (IDE) 的各个选项,以及从命令行生成.调试和部署项目.使用这些开关从脚本或 .bat 文件(例如每夜生成的脚本)运行 IDE,或以特定配置启动 IDE. 说明 ...
- 使用IP连接SQL SERVER或者配置为连接字符串失败
使用IP连接SQL SERVER或者配置为连接字符串失败 情景一:当在webconfig文件中使用 <add key="ConnectionString" value=& ...
- C++原创应用类库和工具类库
此博文记载着自编C++应用类库和生成器库的源代码的链接地址,并且对库的开发环境.开发过程.缺陷以及改进更新进行说明. 分数类 利用中午的时间,自己在Visual Studio 2013环境下编写了一个 ...