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

Description

World Wide Networks (WWN) is a leading company that operates large telecommunication networks. WWN would like to setup a new network in Borduria, a nice country that recently managed to get rid of its military dictator Kurvi-Tasch
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

The first line contains the number n of cities in the country ( 1<=n<=1000 ) followed by the number q of existing subnetworks ( 0<=q<=8 ). Cities are identified by a unique integer value ranging from 1 to n . The first line is
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

Your program has to write the optimal total cost to interconnect all cities.

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

Sample Explanation: The above instance is shown in Figure 2. An optimal solution is described in Figure 3 (thick edges come from an existing network while thin edges have been setup from scratch).








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 最小生成树)的更多相关文章

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

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

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

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

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

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

  4. POJ(2784)Buy or Build

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

  5. Poj(2784),二进制枚举最小生成树

    题目链接:http://poj.org/problem?id=2784 Buy or Build Time Limit: 2000MS   Memory Limit: 65536K Total Sub ...

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

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

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

    先求出原图的最小生成树,然后枚举买哪些套餐,把一个套餐内的点相互之间边权为0,直接用并查集缩点.正确性是基于一个贪心, 在做Kruskal算法是,对于没有进入最小生成树的边,排序在它前面的边不会减少. ...

  8. 【UVA 1151】 Buy or Build (有某些特别的东东的最小生成树)

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

  9. 【最小生成树+子集枚举】Uva1151 Buy or Build

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

随机推荐

  1. android GPS 定位,取位置信息

    现在很多app ,需要取位置信息,所以我也做了一个模块用来取位置信息:   加入位置服务所需的权限: <uses-permission android:name="android.pe ...

  2. 移动web——bootstrap媒体对象

    基本模板 1.这些组件都具有在文本内容的左或右侧对齐的图片(就像博客评论或 Twitter 消息等) <div class="media"> <div class ...

  3. 回顾Google IO 2016 -Keynote【图解】

    Google IO大会倒计时进行中~~ 两名演奏者在使用高空“古筝”. 最后5秒倒计时~~~~全场轰动~ 倒计时结束,IO大会正式开始.屏幕中,一个人把纯白的唱片放入唱片机中. 然后欢快的音乐响起,台 ...

  4. FusionCharts 更新 chart data 数据

    var AlarmChart = null; function alarmChartReBuild(totalNum, alarmNum) { var alarmPart = (alarmNum * ...

  5. Git学习总结三(工作区和暂存区、撤销修改)

    工作区和暂存区 工作区(Working Directory) 就是你在电脑里能看到的目录,比如我的learngit文件夹就是一个工作区: 版本库(Repository) 工作区有一个隐藏目录.git, ...

  6. flutter 环境搭建

    环境: ladder什么的是必不可少的 win10 + Idea 2019.1.13 + Genymotion 2.12 基本可以在模拟器中运行项目,还有些许小问题,但是可以看到效果了 基本流程 下载 ...

  7. 【上海站】EOLINKER 用户培训之旅,等你来共建API新连接

    从今年3月4日起,EOLINKER AMS 团队将再次开启全国用户培训之旅.本次全国培训之旅依旧将覆盖北上广深等国内主要城市,重点提供两种服务内容,一是 对 EOLINKER 产品的交流,包括 API ...

  8. Uncaught TypeError: str.replace is not a function

    在做审核页面时,点击审核通过按钮不执行 后来F12控制台查看发现有报错 是因为flisnullandxyzero未执行 然后找出这个方法,此方法为公共方法,将这个方法复制出来 然后使用console. ...

  9. 【LeetCode】2、Add Two Numbers

    题目等级:Medium 题目描述:   You are given two non-empty linked lists representing two non-negative integers. ...

  10. 不抛异常的swap函数

    namespace AStuff{ template<typename T> class A { public: void swap(A *other) { using std::swap ...