POJ 2784 Buy or Build

来源:互联网 发布:如何在mac上卸载程序 编辑:程序博客网 时间:2024/05/16 18:15

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 32 4 1 23 3 3 6 73 9 2 4 50 24 02 04 21 30 54 4

Sample Output

17

题意:给你n个点,q个套餐。其中套餐表示你只需要支付该套餐的钱,就可以让该套餐上的城市连通。接下来是n个城市的坐标。现在要你求出能连通n个点的最小的价值


思路:这道题目还是难了我一天,之前许多的细节问题都没有考虑好。

实际上你只需要先找出当前的最小生成树,然后再跟你选了几个套餐之后的最小生成树比较,找出最小值就可以了!

AC代码:

#include<stdio.h>#include<string.h>#include<math.h>#include<algorithm>using namespace std;const int N=1000+5;int f[N];int n,m;int x[N],y[N],r[N];int tao[8][N];int val[8],cnt,q1[8];struct p{    int u,v,w;}num[N*(N-1)/2];int find(int x){    if(x!=f[x])        f[x]=find(f[x]);    return f[x];}bool cmp(p x,p y){    return x.w<y.w;}void init(){    for(int i=0;i<=n;i++)        f[i]=i;}int kruskal(){    int i,tot=0,ans=0;    for(i=0;i<cnt&&tot<n-1;i++)    {        int a=find(num[i].u);        int b=find(num[i].v);        if(a==b)            continue;        ans+=num[i].w;        f[a]=b;        tot--;    }    return ans;}int juli(int i,int j){    return (x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]);}int main(){    int i,j,q,sum,k;    while(scanf("%d %d",&n,&q)!=EOF)    {        for(i=0;i<q;i++)        {            scanf("%d %d",&q1[i],&val[i]);            for(j=0;j<q1[i];j++)                scanf("%d",&tao[i][j]);        }        for(i=1;i<=n;i++)            scanf("%d %d",&x[i],&y[i]);        cnt=0;        for(i=1;i<=n;i++)        {            for(j=i+1;j<=n;j++)            {                num[cnt].u=i;                num[cnt].v=j;                num[cnt++].w=juli(i,j);            }        }        sort(num,num+cnt,cmp);        init();        sum=kruskal();        for(int s=1;s<(1<<q);s++)  //枚举你要选几个套餐        {            int cost=0;            init();            for(j=0;j<q;j++)            {                if(!((s>>j)&1)) continue;                cost+=val[j];                for(int k=1;k<q1[j];k++)                {                    int a=find(tao[j][k]);                    int b=find(tao[j][0]);                    if(a!=b)                        f[a]=b;                }            }            sum=min(cost+kruskal(),sum);       //加套餐之后的最小生成树的值        }        printf("%d\n",sum);    }    return 0;}


0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 被客户315投诉了怎么办 给人打不接受调解怎么办 失业证年审忘了怎么办 工商年检过期4天怎么办 个体营业执照年审过期了怎么办 企业年报密码忘了怎么办 税务年报报错了怎么办 工商证过期5年怎么办 车年检标志丢了怎么办 年检标志打错了怎么办 贵州个体出租车工商执照年检怎么办 驾驶证考试预约提示网络繁忙怎么办 帝豪显示屏花屏怎么办 注册公司居委会不盖章怎么办 营业执照名字和店名不一样怎么办 开炸鸡店没经验怎么办 提名候选人时重名重姓怎么办 别人用我的店名怎么办 wish店铺出现侵权产品怎么办 如果公司缺人该怎么办 鲁班奖证书丢了怎么办 个人注册服务号没有营业执照怎么办 社保过了缴费日怎么办 被评为d级纳税人怎么办 忘了税号tfn怎么办 个体户没有办税务登记怎么办 遇征地企业不搬怎么办 dnf账号改错名了怎么办 银行卡绑定的手机号码换了怎么办 支付宝手机号码换了怎么办 淘宝账号被注销了怎么办 注销淘宝号绑定的手机号怎么办 淘宝账号不小心注销了怎么办 淘宝旧密码忘了怎么办 淘宝登录原始密码忘记了怎么办 微信原始密码忘记了怎么办 优酷会员重复交费怎么办 微信解绑手机号密码忘了怎么办 闪银呼呼逾期5天怎么办 忘记淘宝账号和密码怎么办 蘑菇街账号忘了怎么办