先求出原图的最小生成树,然后枚举买哪些套餐,把一个套餐内的点相互之间边权为0,直接用并查集缩点。正确性是基于一个贪心,

在做Kruskal算法是,对于没有进入最小生成树的边,排序在它前面的边不会减少。

边比较多,用prim求最小生成树,效果比Kruskal好,枚举套餐的时候在用Kruskal。

prim和dijkstra的区别在于点距离的定义。

#include<bits/stdc++.h>
using namespace std;
const int maxn = ;
int n,q; int C[];
vector<int> Buy[];
#define PB push_back int x[maxn],y[maxn];
#define squ(x) ((x)*(x)) int dist(int a,int b) { return squ(x[a]-x[b])+squ(y[a]-y[b]); } struct Edge
{
int u,v,w;
Edge(){}
Edge(int u,int v,int w):u(u),v(v),w(w){}
bool operator < (const Edge& x) const {
return w > x.w;
}
}edges[maxn]; bool EdgeLess(const Edge &x,const Edge &y) { return x.w < y.w; } int ecnt; int d[maxn];
bool done[maxn];
const int INF = 0x3f3f3f3f; int Prim()
{
fill(d,d+n,INF);
fill(done,done+n,);
ecnt = ;
priority_queue<Edge> q;
q.push(Edge(-,,)); // dummy edge
int tot = d[] = ;
while(q.size()){
Edge x = q.top(); q.pop();
if(done[x.v]) continue;
edges[ecnt++] = x;
tot += x.w;
done[x.v] = true;
for(int i = ; i < n; i++){
if(done[i]) continue;
int cost = dist(x.v,i);
if(d[i]>cost){
d[i] = cost;
q.push(Edge(x.v,i,cost));
}
}
}
return tot;
} int pa[maxn];
int Find(int x) { return x==pa[x]?x:pa[x]=Find(pa[x]); }
void Union(int a,int b,int &cnt)
{
int s1 = Find(a),s2 = Find(b);
if(s1 != s2){
pa[s1] = s2; cnt--;
}
} int Kruskal(int cnt)
{
if(!cnt) return ;
int ans = ;
for(int i = ; i < ecnt; i++){
Edge &e = edges[i];
int s1 = Find(e.u), s2 = Find(e.v);
if(s1 != s2) { ans += e.w; pa[s1] = s2; cnt--; if(!cnt) return ans; } }
return ans;
} int main()
{
//freopen("in.txt","r",stdin);
int T; scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&q);
for(int i = ; i < q; i++){
int t; scanf("%d%d",&t,C+i);
Buy[i].clear();
while(t--) {
int c; scanf("%d",&c);
Buy[i].PB(c-);
}
}
for(int i = ; i < n; i++){
scanf("%d%d",x+i,y+i);
}
int ans = Prim();
sort(edges+,edges+ecnt,EdgeLess); for(int mask = ,M = <<q; mask < M; mask++){
for(int i = ; i < n; i++) pa[i] = i;
int tot = ,cnt = n-; for(int i = ; i < q; i++){
if(mask&<<i){
tot += C[i];
for(int j = ; j < Buy[i].size(); j++) {
Union(Buy[i][],Buy[i][j],cnt);
}
}
} tot += Kruskal(cnt);
ans = min(ans,tot);
}
printf("%d\n",ans);
if(T) putchar('\n');
}
return ;
}

UVA 1151 Buy or Build (最小生成树)的更多相关文章

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

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

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

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

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

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

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

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

  5. UVa 1151 Buy or Build (最小生成树+二进制法暴力求解)

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

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

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

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

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

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

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

  9. UVA 1151二进制枚举子集 + 最小生成树

    题意:平面上有n个点(1<=N<=1000),你的任务是让所有n个点连通,为此, 你可以新建一些边,费用等于两个端点的欧几里得距离的平方.另外还有q(0<=q<=8)个套餐(数 ...

随机推荐

  1. 1.5-1.6 oozie部署

    一.部署 可参考文档:http://archive.cloudera.com/cdh5/cdh/5/oozie-4.0.0-cdh5.3.6/DG_QuickStart.html 1.解压oozie ...

  2. Eclipse中实现JS代码提示功能

    转发: 用Eclipse写js代码时没有提示,很烦,心累: 找个各种方法以及插件,试了一下,个人感觉AngularJS Eclipse 插件很强,好用,不多说,先装上: 然后重启Eclipse ,右键 ...

  3. POJ - 2676 Sudoku 数独游戏 dfs神奇的反搜

    Sudoku Sudoku is a very simple task. A square table with 9 rows and 9 columns is divided to 9 smalle ...

  4. VS Supercharger插件

    一.前言 Supercharger 是 VS 的一款插件,针对代码进行优化和着色,便于观察和区分. 二.下载及安装 下载的 URL 如下:Supercharger 下载地址 点击下载,下载完成以后,那 ...

  5. Codeforces710C【数学】

    n阶幻方问题::http://blog.csdn.net/fengchaokobe/article/details/7437767 学一下就好啦~ 奇幻七绝 先填上行正中央, 依次斜填切莫忘. 上格没 ...

  6. opengl VAO ,VBO

    A Vertex Array Object (VAO) is an object which contains one or more Vertex Buffer Objects and is des ...

  7. 部署spark 1.3.1 standalong模式

    之前已经写过很多次部署spark 的博客,但是之前部署都是照瓢画葫芦,不得其中的细节,并且以前都是部署spark on yarn 部署环境 scala 2.10.2,jdk 1.6,spark 版本1 ...

  8. ZooKeeper应用案例

    我们通过学习借鉴,哪些项目或应用都使用了ZooKeeper,可以了解我们的应用使用ZooKeeper是否能真正地带来价值,当然,有些项目可能也未必非常适合使用ZooKeeper,我们要批判地学习.借鉴 ...

  9. 关于java中的不可变类(转)

    如何在Java中写出Immutable的类? 要写出这样的类,需要遵循以下几个原则: 1)immutable对象的状态在创建之后就不能发生改变,任何对它的改变都应该产生一个新的对象. 2)Immuta ...

  10. 接口测试02 - 无法绕过的json解析

    概述: 先瞧一下什么是json.JSON(JavaScript Object Notation,JS对象标记)是一种轻量级的数据交换格式. 它基于ECMAScript(w3c定制的js规范)的一个子集 ...