UVa1151 Buy or Build
填坑(p.358)
以前天真的以为用prim把n-1条边求出来就可以
现在看来是我想多了
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<iostream> const int N = + ; struct Node {
int x, y;
Node(int x = , int y = ) : x(x), y(y) {}
}p[N]; int sqr(int x) {
return x * x;
} int dist(const Node& a, const Node& b) {
return sqr(a.x - b.x) + sqr(a.y - b.y);
} struct Edge {
int u, v, w;
Edge() {}
Edge(int u, int v, int w) : u(u), v(v), w(w) {}
bool operator < (const Edge& rhs) const {
return w < rhs.w;
}
};
#include<vector>
std::vector<Edge> edges, pree; int n, ans;
int d[N], pre[N], dis[N][N];
bool inMST[N]; void prim() {
memset(d, 0x3f, sizeof d);
memset(inMST, , sizeof inMST);
ans = d[] = ;
for(int i = ; i < n; i++) {
int u = -;
for(int v = ; v < n; v++) if(!inMST[v]) {
if(u == - || d[v] < d[u]) u = v;
}
inMST[u] = ;
ans += d[u];
if(i) edges.push_back(Edge(u, pre[u], dis[u][pre[u]]));
for(int v = ; v < n; v++) if(!inMST[v]) {
if(d[v] > d[u] + dis[u][v]) {
d[v] = d[u] + dis[u][v];
pre[v] = u;
}
}
}
} int fa[N];
int find(int x) {
return fa[x] == x ? x : fa[x] = find(fa[x]);
} bool merge(int x, int y) {
x = find(x), y = find(y);
if(x == y) return ;
return fa[x] = y, ;
} void UFS_init() {
for(int i = ; i < n; i++) fa[i] = i;
} void pre_kruskal() {
for(int i = ; i < n; i++) {
for(int j = i + ; j < n; j++) {
pree.push_back(Edge(i, j, dis[i][j]));
}
}
sort(pree.begin(), pree.end()); UFS_init();
int MST = n;
ans = ;
for(unsigned i = ; i < pree.size(); i++) {
const Edge& e = pree[i];
if(merge(e.u, e.v)) {
edges.push_back(e);
ans += e.w;
if(--MST == ) break;
}
}
} int q;
#include<vector>
std::vector<int> frees[];
int cost[];
#include<cassert>
void Kruskal(int mask) {
UFS_init();
int MST = n, res = ;
for(int j = ; j < q; j++) if(mask >> j & ) {
res += cost[j];
for(unsigned i = ; i < frees[j].size(); i++) {
MST -= merge(frees[j][i-], frees[j][i]);
}
} for(unsigned i = ; i < edges.size(); i++) {
if(MST == ) break;
if(merge(edges[i].u, edges[i].v)) res += edges[i].w, MST--;
}
assert(MST == );
ans = std::min(ans, res);
} int main() {
#ifdef DEBUG
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
#endif int T; scanf("%d", &T);
while(T--) {
pree.clear();
edges.clear();
scanf("%d%d", &n, &q);
for(int i = ; i < q; i++) {
int m;
scanf("%d%d", &m, cost + i);
frees[i].resize(m);
for(int j = ; j < m; j++) {
scanf("%d", &frees[i][j]);
--frees[i][j];
}
}
for(int i = ; i < n; i++) {
scanf("%d%d", &p[i].x, &p[i].y);
for(int j = ; j < i; j++) {
dis[i][j] = dis[j][i] = dist(p[i], p[j]);
}
}
pre_kruskal();
std::sort(edges.begin(), edges.end());
for(int mask = ; mask < ( << q); mask++) {
Kruskal(mask);
} printf("%d\n", ans);
if(T) puts("");
} return ;
}
UVa1151 Buy or Build的更多相关文章
- 【最小生成树+子集枚举】Uva1151 Buy or Build
Description 平面上有n个点(1<=N<=1000),你的任务是让所有n个点连通,为此,你可以新建一些边,费用等于两个端点的欧几里得距离的平方. 另外还有q(0<=q< ...
- POJ(2784)Buy or Build
Buy or Build Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 1369 Accepted: 542 Descr ...
- Buy or Build (poj 2784 最小生成树)
Buy or Build Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 1348 Accepted: 533 Descr ...
- Buy or Build(UVa1151)
如果枚举每个套餐,并每次都求最小生成树,总时间复杂度会很高,因而需要先求一次原图的最小生成树,则枚举套餐之后需要考虑的边大大减少了. 具体见代码: #include<cstdio> #in ...
- 洛谷 题解 UVA1151 【买还是建 Buy or Build】
[题意] 平面上有\(n(n<=1000)\)个点,你的任务是让所有n个点联通.为此,你可以新建一些边,费用等于两个端点的欧几里得距离平方.另外还有\(q(q<=8)\)个套餐可以购买,如 ...
- UVA 1151 Buy or Build MST(最小生成树)
题意: 在平面上有n个点,要让所有n个点都连通,所以你要构造一些边来连通他们,连通的费用等于两个端点的欧几里得距离的平方.另外还有q个套餐,可以购买,如果你购买了第i个套餐,该套餐中的所有结点将变得相 ...
- UVA 1151 Buy or Build (最小生成树)
先求出原图的最小生成树,然后枚举买哪些套餐,把一个套餐内的点相互之间边权为0,直接用并查集缩点.正确性是基于一个贪心, 在做Kruskal算法是,对于没有进入最小生成树的边,排序在它前面的边不会减少. ...
- UVA 1151 Buy or Build (MST最小生成树,kruscal,变形)
题意: 要使n个点之间能够互通,要使两点直接互通需要耗费它们之间的欧几里得距离的平方大小的花费,这说明每两个点都可以使其互通.接着有q个套餐可以选,一旦选了这些套餐,他们所包含的点自动就连起来了,所需 ...
- UVa 1151 (枚举 + MST) Buy or Build
题意: 平面上有n个点,现在要把它们全部连通起来.现在有q个套餐,如果购买了第i个套餐,则这个套餐中的点全部连通起来.也可以自己单独地建一条边,费用为两点欧几里得距离的平方.求使所有点连通的最小费用. ...
随机推荐
- STUN/TURN/ICE协议在P2P SIP中的应用(二)
1 说明 2 打洞和穿越的概念... 1 3 P2P中的打洞和穿越... 2 4 使用STUN系列 协议穿越的特点... 2 5 STUN/ ...
- Win32中GDI+应用(五)--GDI与GDI+编程模型的区别
在GDI里面,你要想开始自己的绘图工作,必须先获取一个device context handle,然后把这个handle作为绘图复方法的一个参数,才能完成任务.同时,device context ha ...
- BitMap(比特位)
所谓的Bit-map就是用一个bit位来标记某个元素对应的Value, 而Key即是该元素.由于采用了Bit为单位来存储数据,因此在存储空间方面,可以大大节省. 腾讯面试的时候,让写了一个BitMap ...
- C# 禁止 Webbrowser 控件的弹出脚本错误对话框
当IE浏览器遇到脚本错误时浏览器,左下 角会出现一个黄色图标,点击可以查看脚本错误的详细信息,并不会有弹出的错误信息框.当我们使用 WebBrowser控件时有错误信息框弹出,这样程序显的很不友好,而 ...
- [CSS]float&clear浮动
CSS float 属性 浮动的框可以向左或向右移动,直到它的外边缘碰到包含框或另一个浮动框的边框为止. 由于浮动框不在文档的普通流中,所以文档的普通流中的块框表现得就像浮动框不存在一样. 可取的值 ...
- js实现中文转拼音
首先需要注意ES6在严格模式下中常量太长会出问题,CHAR_DICT.FULL_DICT.POLYPHONE都是很大的常量,所以我都外部加载了,否则编译运行会有问题,先贴代码,常量在最后,如下: js ...
- [BZOJ 1907] 树的路径覆盖 【树形DP】
题目链接:BZOJ - 1907 题目分析 使用树形 DP,f[x][0] 表示以 x 为根的子树不能与 x 的父亲连接的最小路径数(即 x 是一个折线的拐点). f[x][1] 表示以 x 为根的子 ...
- 树莓派(jessie)制作服务并开机启动
/etc/init.d/xware #!/bin/sh ### BEGIN INIT INFO # Provides: svn_serve # Required-Start: $remote_fs # ...
- 51,PIC,AVR单片机它们的优点缺点都有哪些?
我有幸接触了几款单片机,并用它们做了一些项目.现在想做个小总结,谈一下自己用各种单片机的感受.仅是个人意见,仁者见仁智者见智. 传统51,我想我就不多说了,适合菜鸟入门,容易上手,价格一般(从性价比方 ...
- RSA算法原理(一)
如果你问我,哪一种算法最重要? 我可能会回答"公钥加密算法". 因为它是计算机通信安全的基石,保证了加密数据不会被破解.你可以想象一下,信用卡交易被破解的后果. 进入正题之前,我先 ...