uva1151 Buy or Build

来源:互联网 发布:缩小手机屏幕的软件 编辑:程序博客网 时间:2024/06/06 03:45

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. 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 de ned 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 w c 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). Input The
input begins with a single positive integer on a line by itself
indicating the number of the cases following, each of them as
described below. This line is followed by a blank line, and there is
also a blank line between two consecutive inputs. Each test case is
described by one input le that contains all the relevant data. The
rst 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 identi ed by a unique integer value ranging from 1 to n . The rst
line is followed by q lines (one per subnetwork), all of them
following the same pattern: The rst integer is the number of cities
in the subnetwork. The second integer is the the cost of the
subnetwork (not greater than 2  10 6 ). The remaining integers on the
line (as many as the number of cities in the subnetwork) are the
identi ers of the cities in the subnetwork. The last part of the le
contains n lines that provide the coordinates of the cities (city 1 on
the rst 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 For each test case, your program has
to write the optimal total cost to interconnect all cities. The
outputs of two consecutive cases will be separated by a blank line. A
115 Cities Instance Consider a 115 cities instance of the problem with
4 subnetworks (the 4 rst graphs in Figure 1). As mentioned earlier
the exact shape of a subnetwork is not relevant still, to keep gures
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 rst 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.

先在原图上求最小生成树,这一次没有用到的边以后更不会用到。枚举购买哪些套餐,之后kruskal只用在剩下的n-1条边里选,总的时间复杂度O(n^2 * logn + 2^q * n)。

#include<cstdio>#include<cstring>#include<algorithm>using namespace std;#define LL long longLL oo=1e16;struct edge{    int u,v,w;    bool operator < (const edge & rhs) const    {        return w<rhs.w;    }}g[1000010],a[1010];int m,n,q,fa[1010],num[10],f[10][1010],w[10],tot,xx[1010],yy[1010];LL ans;LL dis(int i,int j){    return (LL)(xx[i]-xx[j])*(xx[i]-xx[j])+(yy[i]-yy[j])*(yy[i]-yy[j]);}int find(int x){    return x==fa[x]?x:fa[x]=find(fa[x]);}void init(){    int i,j;    ans=oo;    scanf("%d%d",&n,&q);    for (i=1;i<=q;i++)    {        scanf("%d%d",&num[i],&w[i]);        for (j=1;j<=num[i];j++)          scanf("%d",&f[i][j]);    }    for (i=1;i<=n;i++)      scanf("%d%d",&xx[i],&yy[i]);    tot=0;    for (i=1;i<=n;i++)      for (j=i+1;j<=n;j++)        g[++tot]=(edge){i,j,dis(i,j)};    sort(g+1,g+tot+1);}void pre(){    int i,cnt=0;    for (i=1;i<=n;i++)      fa[i]=i;    for (i=1;cnt<n-1;i++)      if (find(g[i].u)!=find(g[i].v))      {        fa[fa[g[i].u]]=fa[g[i].v];        a[++cnt]=g[i];      }}void solve(int k){    LL ret=0;    int i,j,u,v,cnt=0;    for (i=1;i<=n;i++)      fa[i]=i;    for (i=1;i<=q;i++)      if (k&(1<<(i-1)))      {        ret+=w[i];        for (j=1;j<num[i];j++)        {            u=find(f[i][j]);            v=find(f[i][j+1]);            if (u!=v)            {                fa[u]=v;                cnt++;            }        }      }    for (i=1;cnt<n-1;i++)      if (find(a[i].u)!=find(a[i].v))      {        ret+=a[i].w;        cnt++;        fa[fa[a[i].u]]=fa[a[i].v];      }    ans=min(ans,ret);}int main(){    int i,T;    scanf("%d",&T);    while (T--)    {        init();        pre();        for (i=0;i<(1<<q);i++)          solve(i);        printf("%lld\n",ans);        if (T) printf("\n");    }}
0 0
原创粉丝点击