题意:

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

分析:

很明显,如果没有这些套餐的话,就是一个裸的MST。

可以枚举套餐的组合情况,然后把套餐中的边的权值置为0,再求MST。

在求MST的过程中,并不需要把所有的边都加进来。只要把原图的MST的那些边和套餐中的边加进来即可。

因为,对于不在原图的MST的边,购买套餐以后,按照权值排序,排在它之前的边不会减少,反而会因为购买套餐而在前面多出来一些权值为0的边。所以原图中被“淘汰”的边,在购买套餐后也一定会被“淘汰”。

 #include <cstdio>
#include <vector>
#include <algorithm>
using namespace std; const int maxn = + ;
const int maxq = ;
int n;
int x[maxn], y[maxn], cost[maxq];
vector<int> subn[maxq]; int pa[maxn];
int findset(int x) { return x == pa[x] ? x : pa[x] = findset(pa[x]); } struct Edge
{
int u, v, d;
Edge(int u, int v, int d):u(u), v(v), d(d) {}
bool operator < (const Edge& rhs) const { return d < rhs.d; }
}; int MST(int cnt, vector<Edge>& e, vector<Edge>& used)
{
if(cnt == ) return ;
int m = e.size();
int ans = ;
used.clear();
for(int i = ; i < m; ++i)
{
int u = findset(e[i].u), v = findset(e[i].v);
if(u != v)
{
pa[u] = v;
ans += e[i].d;
used.push_back(e[i]);
if(--cnt == ) break;
}
}
return ans;
} int main()
{
//freopen("in.txt", "r", stdin);
int T;
scanf("%d", &T);
while(T--)
{
int q;
scanf("%d%d", &n, &q);
for(int i = ; i < q; ++i)
{
int cnt;
scanf("%d%d", &cnt, &cost[i]);
subn[i].clear();
while(cnt--)
{
int u;
scanf("%d", &u);
subn[i].push_back(u-); //代码中节点的编号是从0开始的
}
}
for(int i = ; i < n; ++i) scanf("%d%d", &x[i], &y[i]); vector<Edge> e, need;
for(int i = ; i < n; ++i)
for(int j = ; j < i; ++j)
{
int c = (x[i]-x[j])*(x[i]-x[j]) + (y[i]-y[j])*(y[i]-y[j]);
e.push_back(Edge(i, j, c));
} for(int i = ; i < n; ++i) pa[i] = i;
sort(e.begin(), e.end()); int ans = MST(n, e, need);
for(int S = ; S < (<<q); ++S)
{//枚举所有套餐的组合情况
for(int i = ; i < n; ++i) pa[i] = i;
int cnt = n, c = ;
for(int i = ; i < q; ++i) if(S & (<<i))
{
c += cost[i];
for(int j = ; j < subn[i].size(); ++j)
{
int u = findset(subn[i][j]), v = findset(subn[i][]);
if(u != v) { --cnt; pa[u] = v; }
}
}
vector<Edge> hehe; //这里只是为了调用函数,所以弄了一个无关紧要的参数
ans = min(ans, c + MST(cnt, need, hehe));
} printf("%d\n", ans);
if(T) printf("\n");
} return ;
}

代码君

UVa 1151 (枚举 + MST) Buy or Build的更多相关文章

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

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

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

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

  3. POJ(2784)Buy or Build

    Buy or Build Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 1369   Accepted: 542 Descr ...

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

    Buy or Build Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 1348   Accepted: 533 Descr ...

  5. 【uva 1151】Buy or Build(图论--最小生成树+二进制枚举状态)

    题意:平面上有N个点(1≤N≤1000),若要新建边,费用是2点的欧几里德距离的平方.另外还有Q个套餐,每个套餐里的点互相联通,总费用为Ci.问让所有N个点连通的最小费用.(2组数据的输出之间要求有换 ...

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

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

  7. Buy or Build UVA - 1151 Kruskal+枚举

    题意: 大概意思是有 n 个点,现在有 q 个方案 ,第 i 个方案耗费为 ci ,使 Ni 个点联通 ,当然也可以直接使两点联通 ,现求最小生成树的代价. 两点直接联通的代价是欧几里得距离的平方: ...

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

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

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

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

随机推荐

  1. discuz x3插件开发傻瓜图文教程,用demo说话

    此demo功能是在模板footer部位插入一段javascript代码,这段代码可以是alert提示,也可以是加载广告等等. 第一步: 在config\config_global.php 文件里设置$ ...

  2. Vb.Net Xml文档格式化

    最近在处理Webservice文档的时候,因为是未格式化的,需要处理,所以有了以下代码. #Region "Xml字符串转换成格式化的XML文件" 'txt_Result.Text ...

  3. JS 原型链图形详解

    JS原型链 这篇文章是「深入ECMA-262-3」系列的一个概览和摘要.每个部分都包含了对应章节的链接,所以你可以阅读它们以便对其有更深的理解. 对象 ECMAScript做为一个高度抽象的面向对象语 ...

  4. 百度地图 获取矩形point

    http://developer.baidu.com/map/jsdemo.htm#f0_7  鼠标绘制点线面 <!DOCTYPE html><html><head> ...

  5. touches获得手指点击的坐标

    -(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { UITouch *touch = [touches anyObjec ...

  6. tableView中不易被注意到的方法

    - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{ } 这个方法 在 r ...

  7. MVC4多语言IHttpModule实现

    最近项目需要多语言环境了. 由于项目页面较多,逐个Action去读取资源文件不大现实.就想到了使用 IHttpModule配合MVC的路由规则来实现. 首先创建以个mvc4的应用程序,添加资源文件夹( ...

  8. js页面刷新一次

    // var str = document.location.hash, // index = str.indexOf("#"); // if(index == 0){ // wi ...

  9. 【NGUI】屏幕自适应(不用UIStretch,用UIRoot)---------------good

    原地址:http://blog.csdn.net/lzhq1982/article/details/18814023 这篇文章是转载的,之前用UIStretch做屏幕自适应,但一直有两个硬伤让我难受, ...

  10. C++11新特性:右值引用和转移构造函数

    问题背景 #include <iostream> using namespace std; vector<int> doubleValues (const vector< ...