Buy or Build (poj 2784 最小生成树)
Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 1348 | Accepted: 533 |
Description
and which is now seeking for investments of international companies (for a complete description of Borduria, have a look to the following Tintin albums ``King Ottokar's Sceptre", ``The Calculus Affair" and ``Tintin and the Picaros"). You are requested to help
WWN todecide how to setup its network for a minimal total cost.
Problem
There are several local companies running small networks (called subnetworks in the following) that partially cover the n largest cities of Borduria. WWN would like to setup a network that connects all n cities. To achieve this, it can either build edges between
cities from scratch or it can buy one or several subnetworks from local companies. You are requested to help WWN to decide how to setup its network for a minimal total cost.
- All n cities are located by their two-dimensional Cartesian coordinates.
- There are q existing subnetworks. If q>=1 then each subnetwork c ( 1<=c<=q ) is defined by a set of interconnected cities (the exact shape of a subnetwork is not relevant to our problem).
- A subnetwork c can be bought for a total cost wc and it cannot be split (i.e., the network cannot be fractioned).
- To connect two cities that are not connected through the subnetworks bought, WWN has to build an edge whose cost is exactly the square of the Euclidean distance between the cities.
You have to decide which existing networks you buy and which edges you setup so that the total cost is minimal. Note that the number of existing networks is always very small (typically smaller than 8).
A 115 Cities Instance
Consider a 115 cities instance of the problem with 4 subnetworks (the 4 first graphs in Figure 1). As mentioned earlier the exact shape of a subnetwork is not relevant still, to keep figures easy to read, we have assumed an arbitrary tree like structure for
each subnetworks. The bottom network in Figure 1 corresponds to the solution in which the first and the third networks have been bought. Thin edges correspond to edges build from scratch while thick edges are those from one of the initial networks.
Input
followed by q lines (one per subnetwork), all of them following the same pattern: The first integer is the number of cities in the subnetwork. The second integer is the the cost of the subnetwork (not greater than 2 x 106 ). The remaining integers
on the line (as many as the number of cities in the subnetwork) are the identifiers of the cities in the subnetwork. The last part of the file contains n lines that provide the coordinates of the cities (city 1 on the first line, city 2 on the second one,
etc). Each line is made of 2 integer values (ranging from 0 to 3000) corresponding to the integer coordinates of the city.
Output
Sample Input
7 3
2 4 1 2
3 3 3 6 7
3 9 2 4 5
0 2
4 0
2 0
4 2
1 3
0 5
4 4
Sample Output
17
Hint
Figure 3: An optimal solution of the 7 City instance in which which the first and second existing networkshave been bought while two extra edges (1, 5) and (2, 4)
Source
题意:n个城市,告诉每一个城市的坐标,还有q个联通块,如今要把这n个城市连起来,能够购买联通块(每一个有一定的费用),或者新建一条边(费用为点之间的距离的平方)。问最小费用是多少。
思路:q非常小。二进制枚举选哪些块。每次kruskal一遍,求最小值。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <string>
#include <map>
#include <stack>
#include <vector>
#include <set>
#include <queue>
#pragma comment (linker,"/STACK:102400000,102400000")
#define mod 1000000009
#define INF 0x3f3f3f3f
#define pi acos(-1.0)
#define eps 1e-6
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
#define FRE(i,a,b) for(i = a; i <= b; i++)
#define FREE(i,a,b) for(i = a; i >= b; i--)
#define FRL(i,a,b) for(i = a; i < b; i++)
#define FRLL(i,a,b) for(i = a; i > b; i--)
#define mem(t, v) memset ((t) , v, sizeof(t))
#define sf(n) scanf("%d", &n)
#define sff(a,b) scanf("%d %d", &a, &b)
#define sfff(a,b,c) scanf("%d %d %d", &a, &b, &c)
#define pf printf
#define DBG pf("Hi\n")
typedef long long ll;
using namespace std; const int maxn = 1005;
const int MAXN = 500500; struct Node
{
int x,y;
}node[maxn]; struct Edge
{
int u,v,len;
bool operator<(const Edge &a)const
{
return len<a.len;
}
}edge[MAXN]; int father[maxn],cost[10];
int n,q,num;
vector<int>g[10]; void init()
{
for (int i=0;i<=n;i++)
father[i]=i;
} void addedge(int u,int v)
{
edge[num].u=u;
edge[num].v=v;
edge[num++].len=(node[u].x-node[v].x)*(node[u].x-node[v].x)+(node[u].y-node[v].y)*(node[u].y-node[v].y);
} int find_father(int x)
{
if (x!=father[x])
father[x]=find_father(father[x]);
return father[x];
} bool Union(int a,int b)
{
int fa=find_father(a);
int fb=find_father(b);
if (fa==fb) return false;
father[fa]=fb;
return true;
} int Kruskal()
{
int ans=0;
int cnt=0;
for (int i=0;i<num;i++)
{
if (Union(edge[i].u,edge[i].v))
{
ans+=edge[i].len;
cnt++;
}
if (cnt==n-1) break;
}
return ans;
} void solve()
{
init();
int ans=Kruskal();
for (int i=0;i<(1<<q);i++)
{
init();
int all=0;
for (int j=0;j<q;j++)
{
if (!((i>>j)&1)) continue;
all+=cost[j];
for (int k=1;k<g[j].size();k++)
Union(g[j][k],g[j][0]);
}
ans=min(ans,all+Kruskal());
}
pf("%d\n",ans);
} int main()
{
int i,j,t,number,x;
// sf(t);
// while (t--)
{
sff(n,q);
num=0;
for (i=0;i<q;i++)
{
g[i].clear();
sff(number,cost[i]);
for (j=0;j<number;j++)
{
sf(x);
g[i].push_back(x);
}
}
for (i=1;i<=n;i++)
sff(node[i].x,node[i].y);
for (i=1;i<=n;i++)
for (j=i+1;j<=n;j++)
addedge(i,j);
sort(edge,edge+num);
solve();
// if (t) puts("");
}
return 0;
}
/*
1 7 3
2 4 1 2
3 3 3 6 7
3 9 2 4 5
0 2
4 0
2 0
4 2
1 3
0 5
4 4
*/
Buy or Build (poj 2784 最小生成树)的更多相关文章
- uva 1151 - Buy or Build poj 2784 Buy or Build(最小生成树)
最小生成树算法简单 只是增加了一些新的东西,对于需要最小生成树算法 和中 并检查使用的一系列 还有一些更深入的了解. 方法的一些复杂问题 #include<cstdio> #include ...
- UVA 1151 Buy or Build (MST最小生成树,kruscal,变形)
题意: 要使n个点之间能够互通,要使两点直接互通需要耗费它们之间的欧几里得距离的平方大小的花费,这说明每两个点都可以使其互通.接着有q个套餐可以选,一旦选了这些套餐,他们所包含的点自动就连起来了,所需 ...
- 【uva 1151】Buy or Build(图论--最小生成树+二进制枚举状态)
题意:平面上有N个点(1≤N≤1000),若要新建边,费用是2点的欧几里德距离的平方.另外还有Q个套餐,每个套餐里的点互相联通,总费用为Ci.问让所有N个点连通的最小费用.(2组数据的输出之间要求有换 ...
- POJ(2784)Buy or Build
Buy or Build Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 1369 Accepted: 542 Descr ...
- Poj(2784),二进制枚举最小生成树
题目链接:http://poj.org/problem?id=2784 Buy or Build Time Limit: 2000MS Memory Limit: 65536K Total Sub ...
- UVA 1151 Buy or Build MST(最小生成树)
题意: 在平面上有n个点,要让所有n个点都连通,所以你要构造一些边来连通他们,连通的费用等于两个端点的欧几里得距离的平方.另外还有q个套餐,可以购买,如果你购买了第i个套餐,该套餐中的所有结点将变得相 ...
- UVA 1151 Buy or Build (最小生成树)
先求出原图的最小生成树,然后枚举买哪些套餐,把一个套餐内的点相互之间边权为0,直接用并查集缩点.正确性是基于一个贪心, 在做Kruskal算法是,对于没有进入最小生成树的边,排序在它前面的边不会减少. ...
- 【UVA 1151】 Buy or Build (有某些特别的东东的最小生成树)
[题意] 平面上有n个点(1<=N<=1000),你的任务是让所有n个点连通,为此,你可以新建一些边,费用等于两个端点的欧几里得距离的平方. 另外还有q(0<=q<=8)个套餐 ...
- 【最小生成树+子集枚举】Uva1151 Buy or Build
Description 平面上有n个点(1<=N<=1000),你的任务是让所有n个点连通,为此,你可以新建一些边,费用等于两个端点的欧几里得距离的平方. 另外还有q(0<=q< ...
随机推荐
- Resources.getResourceAsReader 报空指针
1.maven项目中 可能未编译 导致找不到, 解决方法:mvn clean install -DskipTests -X 编译一下项目 2.可能在 Resources.getResourceAs ...
- JS——旋转木马
1.opacity和zIndex的综合运用 2.样式的数组的替换:向右边滑动---删除样式数组第一位并在数组最后添加:向左边滑动---删除样式数组最后一位并在数组前添加 3.开闭原则,只有当回调函数执 ...
- CSS——float
float:就是在于布局,首先要介绍的是文档流(标准流),之后是浮动布局. 文档流:元素自上而下,自左而右,块元素独占一行,行内元素在一行上显示,碰到父集元素的边框换行. 浮动布局: 1.float: ...
- dotnetnuke 获得List 属性
new DotNetNuke.Common.Lists.ListController().GetListEntryInfo("DataType","Text") ...
- Linux Shell ssh登录脚本
Linux 登陆服务器敲命令太多,某时候确实不便,所以就用shell写了一个 我的blog地址: http://www.cnblogs.com/caoguo 一.说明 支持秘密和密钥两种格式 用户名 ...
- 5.21leetcode练习
目录 两数之和 题目 答案 整数反转 题目 思路及答案 回文数 题目 思路及答案 希望每天进步一点点 两数之和 题目 新手司机上路,光荣翻车,没想出来.借了别人的答案,自行领会 答案 整数反转 题目 ...
- Typescript编译设置
TypeScript MSBuild编译选项,用记事本打开工程文件,进行修改,如<TypeScriptGeneratesDeclarations>true</TypeScriptGe ...
- CAD设置图层亮度(com接口)
主要用到函数说明: MxDrawXCustomFunction::Mx_SetLayerBright 设置显示亮度,默认值为100%.详细说明如下: 参数 说明 LPCTSTR pszLayerNam ...
- 可以用作javascript异步模式的函数写法
1. 回调函数 f1(); f2(); function f1(callback) { setTimeout(function() { // f1的任务代码 callback(); }, 1000); ...
- 从0开始复习JS---1、函数复习
1. 写一个函数,实现对数字数组的排序. function get_order(array){ for(var i = 0; i <array.length-1; i++){ for(var j ...