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

原创 2015年07月10日 10:53:33

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
*/



POJ 2784 Buy or Build(二进制枚举 + 最小生成树)

Buy or Build Description World Wide Networks (WWN) is a leading company that operates larg...
  • qq_26658823
  • qq_26658823
  • 2016年09月03日 21:55
  • 198

POJ1287-最小生成树

题目:题目链接   题意:给你一个图,然后求最小花费的图使得所有的点都有被连到   分析:最小生成树,需要注意的是这里的边是更新的,每次都需要判断一下是不是边的权值被更新了。Prime竟然不超...
  • u010057864
  • u010057864
  • 2013年10月03日 20:55
  • 588

poj2253 最小生成树中的最大边 prim

Frogger Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 30620   Accepted: 9875 ...
  • became_a_wolf
  • became_a_wolf
  • 2015年08月19日 09:15
  • 692

最小生成树-两种算法复杂度比较 poj-1258,2485

1.Prim算法 时间是复杂度O(n2),适合稠密图。 例:Poj–1258 题目大意:n个城市建造光缆,要使这些城市直接通信,并且光缆费用最小。 #include #include #de...
  • jichangzhen
  • jichangzhen
  • 2016年08月20日 11:37
  • 1139

poj_1639 Picnic Planning(度限制最小生成树)

Picnic Planning Time Limit: 5000MS   Memory Limit: 10000K Total Submissions: 10431   Accepted:...
  • christry_stool
  • christry_stool
  • 2017年02月07日 00:40
  • 356

最小k限度生成树 +poj(1639)代码

算法引入: 最小k度限制生成树,就是指有特殊的某一点的度不能超过k时的最小生成树; 如果T是G的一个生成树且dT(v0)=k,则称T为G的k度限制生成树; G中权值和最小的k度限制生成树称为G的...
  • sinat_36215255
  • sinat_36215255
  • 2017年08月07日 14:08
  • 136

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

一道很好的最小生成树题目 。 看似非常复杂,其实仔细分析一下算法的复杂度就会发现,如果加入了lrj说的优化,其实复杂度不高 。 就像紫书中说的, 除去购买套餐中的点,剩下的最小边仍然在原始的最小生成树...
  • weizhuwyzc000
  • weizhuwyzc000
  • 2015年08月16日 20:56
  • 627

POJ 2253 Frogger(最小生成树)

题目链接:点击打开链接 题意:求从1到2的路径中, 使得最长路尽量小。 细节参见代码: #include #include #include #include #include #include...
  • weizhuwyzc000
  • weizhuwyzc000
  • 2016年03月05日 10:20
  • 1038

最小生成树--poj2485

Language: Default Highways Time Limit: 1000MS   Memory Limit: 65536K Total Submi...
  • u010660276
  • u010660276
  • 2013年08月19日 20:27
  • 992

poj 1751 (最小生成树 Prime+kruskal 路径输出)

Highways Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 12946   Acce...
  • qq_33406883
  • qq_33406883
  • 2016年07月23日 10:02
  • 445
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Buy or Build (poj 2784 最小生成树)
举报原因:
原因补充:

(最多只允许输入30个字)