题意:给定n个点,你的任务是让它们都连通。你可以新建一些边,费用等于两点距离的平方(当然越小越好),另外还有几种“套餐”,可以购买,你购买的话,那么有些边就可以连接起来,

每个“套餐”,也是要花费的,让你求出最少花费。

析:首先想到的是把所有情况都考虑算一下,然后找出最少的,先算没有“套餐”的,然后算有的,用二进制枚举的话,总时间复杂度为O(2qn2+n2logn),这个时间复杂度太大了吧,肯定会超时,

那么我们就可以优化一下,首先先算出来最小生成树,并且把每条边都保存下来,那么加了“套餐”之后,就不用全部枚举了,这是一个优化,然后在买“套餐”后,那么有的权值就变成了0,

这个也不要加上,再重新枚举,我们在之前就把它们连接上就OK。其他的和最小生成树一样。

代码如下:

#include <cstdio>
#include <iostream>
#include <algorithm> using namespace std;
const int maxn = 1000 + 10;
struct node{
int u, v, w;
bool operator < (const node &p) const {
return w < p.w;
}
};
node a[maxn*maxn/2];
int p[maxn], x[maxn], y[maxn], n, m, q[8][maxn], c[2][10], indx, l[maxn]; int Find(int x){
return x == p[x] ? x : p[x] = Find(p[x]);
} int Kruskal(){//最小生成树
int ans = 0;
l[0] = 0;
for(int i = 0; i < indx; ++i){
int x = Find(a[i].u);
int y = Find(a[i].v);
if(x != y){
ans += a[i].w;
p[x] = y;
l[++l[0]] = i;//把最小生成树的边都保存下来
}
}
return ans;
} int Kruskal2(){//买“套餐”后的最小生成树
int ans = 0;
for(int i = 1; i <= l[0]; ++i){
int ii = l[i];
int x = Find(a[ii].u);
int y = Find(a[ii].v);
if(x != y){
p[x] = y;
ans += a[ii].w;
}
}
return ans;
} int main(){
// freopen("int.txt", "r", stdin);
int T; cin >> T;
while(T--){
scanf("%d %d", &n, &m);
for(int i = 0; i < m; ++i){
scanf("%d %d", &c[0][i], &c[1][i]);
for(int j = 0; j < c[0][i]; ++j)
scanf("%d", &q[i][j]);
}
for(int i = 0; i < n; ++i)
scanf("%d %d", &x[i], &y[i]); indx = 0;
for(int i = 0; i < n; ++i)//计算权植
for(int j = i+1; j < n; ++j){
a[indx].u = i+1;
a[indx].v = j+1;
a[indx++].w = (x[i]-x[j])*(x[i]-x[j]) + (y[i]-y[j])*(y[i]-y[j]);
} sort(a, a+indx);
for(int i = 0; i <= n; ++i) p[i] = i;
int ans = Kruskal();//计算不买”套餐“时的最小费用 for(int i = 0; i < (1<<m); ++i){//二进制法枚举
int cost = 0;
for(int j = 0; j <= n; ++j) p[j] = j; for(int j = 0; j < m; ++j){
if(i&(1<<j)){
cost += c[1][j];
for(int k = 0; k < c[0][j]-1; ++k){
int xx = Find(q[j][k]);
int yy = Find(q[j][k+1]);
if(xx != yy) p[xx] = yy;
}
}
}
ans = min(ans, cost + Kruskal2());//加上买套餐的费用,更新最小值
} printf("%d\n", ans);
if(T) printf("\n");
}
return 0;
}

UVa 1151 Buy or Build (最小生成树+二进制法暴力求解)的更多相关文章

  1. UVa 1151 Buy or Build【最小生成树】

    题意:给出n个点的坐标,现在需要让这n个点连通,可以直接在点与点之间连边,花费为两点之间欧几里得距离的平方,也可以选购套餐,套餐中所含的点是相互连通的 问最少的花费 首先想kruskal算法中,被加入 ...

  2. UVA 1151 Buy or Build MST(最小生成树)

    题意: 在平面上有n个点,要让所有n个点都连通,所以你要构造一些边来连通他们,连通的费用等于两个端点的欧几里得距离的平方.另外还有q个套餐,可以购买,如果你购买了第i个套餐,该套餐中的所有结点将变得相 ...

  3. UVa 1151 - Buy or Build(最小生成树)

    链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...

  4. UVA 1151 Buy or Build (最小生成树)

    先求出原图的最小生成树,然后枚举买哪些套餐,把一个套餐内的点相互之间边权为0,直接用并查集缩点.正确性是基于一个贪心, 在做Kruskal算法是,对于没有进入最小生成树的边,排序在它前面的边不会减少. ...

  5. UVA - 1151 Buy or Build (买还是建)(并查集+二进制枚举子集)

    题意:平面上有n个点(1<=n<=1000),你的任务是让所有n个点连通.可以新建边,费用等于两端点欧几里德距离的平方.也可以购买套餐(套餐中的点全部连通).问最小费用. 分析: 1.先将 ...

  6. UVA 1151 Buy or Build (MST最小生成树,kruscal,变形)

    题意: 要使n个点之间能够互通,要使两点直接互通需要耗费它们之间的欧几里得距离的平方大小的花费,这说明每两个点都可以使其互通.接着有q个套餐可以选,一旦选了这些套餐,他们所包含的点自动就连起来了,所需 ...

  7. uva 1151 - Buy or Build poj 2784 Buy or Build(最小生成树)

    最小生成树算法简单 只是增加了一些新的东西,对于需要最小生成树算法 和中 并检查使用的一系列 还有一些更深入的了解. 方法的一些复杂问题 #include<cstdio> #include ...

  8. UVA 1151 买还是建(最小生成树)

    买还是建 紫书P358 [题目链接]买还是建 [题目类型]最小生成树 &题解: 这题真的心累,看了3天,最后照着码还是wa,先放lrj代码,以后再看吧 &代码: // UVa1151 ...

  9. uva 1151最小生成树

    先求一次最小生成树,可以排除n*(n*1)/2-(n-1)条边,每次利用二进制法枚举套餐的选择,套餐中的点直接处理,如果两个套餐有公共点直接合并,他们一定连通,然后枚举第一步最小生成树得到的n-1条边 ...

随机推荐

  1. C#对象的三种序列化

    要让一个对象支持.Net序列化服务,用户必须为每一个关联的类加上[Serializable]特性.如果类中有些成员不适合参与序列化(比如:密码字段),可以在这些域前加上[NonSerialized]特 ...

  2. 自动化工具 Python 调 Jmeter 执行参数化 jmx 脚本

    烦透了jmeter输入如下鬼命令: Jmeter -n -t {tmpjmxfile} -l {csvfilename} -e -o {htmlreportpath} 尤其是{htmlreportpa ...

  3. Spring Boot 入门之消息中间件篇(五)

    原文地址:Spring Boot 入门之消息中间件篇(五) 博客地址:http://www.extlight.com 一.前言 在消息中间件中有 2 个重要的概念:消息代理和目的地.当消息发送者发送消 ...

  4. Java-Runoob-高级教程-实例-环境设置实例:1.Java 实例 – 如何编译一个Java 文件?

    ylbtech-Java-Runoob-高级教程-实例-环境设置实例:1.Java 实例 – 如何编译一个Java 文件? 1.返回顶部 1. Java 实例 - 如何编译 Java 文件  Java ...

  5. jQuery layer弹出层插件 http://layer.layui.com/直接上官网学

    在许多网站中,经常用到弹出层,有时候为了达到更好的用户体验,你将写繁琐的css跟js,这款 jquery-layer可以让你想到即可做到的web弹窗/层js组件.layer侧重于用户灵活的自定义,为不 ...

  6. 七.jQuery源码解析之.toArray()

    toArray()是将jQuery对象转换成数组 从源码中可以看到,这些常见的方法,都是直接从原生的 javascript中"借鉴"过来的.为什么这么说呢? 225行中,在运行时, ...

  7. JMS消息服务模型

    JMS--仅仅是一种规范,一种接口规约,一种编程模型.类似的JPA,JSR等 场景: 1.多个系统之间交互,实现可以采取RPC,但是交互复杂,基本就是点对点的方式 2.其实交互就是消息,而JMS就是消 ...

  8. [Python] numpy.Matrix

    import numpy as np np.matrix('1, 2; 3, 4') #1, 2 #3, 4 np.matrix([[1,2],[3,4]]) #1, 2 #3, 4

  9. Meet Solr

    you should have a solid understanding of Solr's query and indexing capabilities, including how to pe ...

  10. 1.1_C语言概述

    C语言概述 1.1 什么是C语言 一提到语言这个词语,自然会想到的是像英语.汉语等这样的自然语言,因为它是人和人交换信息不可缺少的工具. 而今天计算机遍布了我们生活的每一个角落,除了人和人的相互交流之 ...