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 买还是建的更多相关文章

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

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

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

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

  3. 洛谷 题解 UVA1151 【买还是建 Buy or Build】

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

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

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

  5. UVA 1151

    /* 题意:有n个点,现在需要联通所有,有q种套餐可以选择, 当然套餐之外也可以自己添加边,意为达到最短距离. 题意很明显,不知道需要使用哪一种套餐, 那么需要枚举每一种套餐的情况. 然后再进行对比. ...

  6. uva 1151(最小生成树,枚举子集)

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

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

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

  8. UVa 1151 (枚举 + MST) Buy or Build

    题意: 平面上有n个点,现在要把它们全部连通起来.现在有q个套餐,如果购买了第i个套餐,则这个套餐中的点全部连通起来.也可以自己单独地建一条边,费用为两点欧几里得距离的平方.求使所有点连通的最小费用. ...

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

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

随机推荐

  1. 【论文阅读】Sliding Line Point Regression for Shape Robust Scene Text Detection

    一.整体网络结构              二.细节                                      n=7,(7+7)*2+4=32个channel 三.结果       ...

  2. caffe学习记录

    结论: caffe网络的prototxt训练与测试的时候用的是不同的,训练的时候用的prototxt里面有test只是为了测试网络的训练程度,里面的测试集是验证集,并不是真正我们测试的时候用的网络定义 ...

  3. [GDAL]写入shp

    C#通过Wkt码构建shp,记录写不进去! static void WriteVectorFile() { string strVectorFile = "E:\\"; // 注册 ...

  4. 解决PHPStorm经常卡顿现象 调整内存限制

    https://www.jisec.com/other/451.html 为什么调整内存? 最近发现PHPstorm在打开一些大点的js, html文件时,会非常的卡顿,这个主要的原因是因为设置的内存 ...

  5. 批量生成反色图片,用PHOTOSHOP批处理功能。

    http://zhidao.baidu.com/link?url=Iz46PDPnEITummTEwo2GtUrK6AeAjlidJ7HtCPJ6NYZJbbllRwNg2iBAcNwF2TYjccP ...

  6. JQ 给textarea赋值

    <textarea id='t1'></textarea> 下面是 jq赋值的三种方式 $("#t1").text("AAA"); $( ...

  7. EditPlus 4.3.2499 中文版已经发布(11月21日更新)

    新的版本修复了如下问题: 文本库的日期快捷方式“^@”失效. 列选模式下“减少缩进量”命令无法执行. 在某些情况下突出显示匹配括号导致程序崩溃.(这个问题是我发现的,电邮告诉作者后,一天之内就修复了) ...

  8. pandas练习(四)--- 应用Apply函数

    探索学生对酒的消费情况 数据见github 步骤1 - 导入必要的库 import pandas as pd import numpy as np 步骤2 - 数据集 path4 = "./ ...

  9. 2018-2019-2 20165209 《网络对抗技术》Exp6:信息搜集与漏洞扫描

    2018-2019-2 20165209 <网络对抗技术>Exp6:信息搜集与漏洞扫描 1 基础问题回答和实验内容 1.1基础问题回答 (1)哪些组织负责DNS,IP的管理. Intern ...

  10. leetcode_目录

    3Sum Closest 3Sum 4Sum Add Binary Add Two Numbers Anagrams Balanced Binary Tree Best Time to Buy and ...