【题意】

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

另外还有q(0<=q<=8)个套餐,可以购买,如果你购买了第i个套餐,该套餐中的所有结点将变得相互连通,第i个套餐的花费为ci。

求最小花费。

Input
 (1 ≤ n ≤ 1000)  (0 ≤ q ≤ 8).

The second integer is the the cost of the subnetwork
(not greater than 2 × 10^6). integer values (ranging from 0 to 3000) 
Output

...

Sample Input
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
Sample Output
17

【分析】

  枚举套餐哦。其实生成树问题多一些东东的话都是枚举的吧?吗?
  你一开始先排序好,枚举完就不用排序了。

LRJ说什么只考虑最小生成树上的边优化版本:

 #include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
#define Maxn 1010
#define INF 0xfffffff int a[][Maxn],c[];
int nx[Maxn],ny[Maxn];
int n,q; struct node
{
int x,y,c;
}t[Maxn*Maxn];
int len,nl; void ins(int x,int y,int c)
{
t[++len].x=x;t[len].y=y;t[len].c=c;
} bool cmp(node x,node y) {return x.c<y.c;} int mymin(int x,int y) {return x<y?x:y;}
int mymax(int x,int y) {return x>y?x:y;} int fa[Maxn];
int ffa(int x)
{
if(fa[x]!=x) fa[x]=ffa(fa[x]);
return fa[x];
} void ffind()
{
int ans=INF;
for(int i=;i<(<<q);i++)
{
int now=;
for(int j=;j<=n;j++) fa[j]=j;
int ft=-;
for(int j=;j<=q;j++) if((<<j-)&i)
{
for(int k=;k<=a[j][];k++)
fa[ffa(a[j][k])]=ffa(a[j][]);
now+=c[j];
}
int cnt=;
for(int j=;j<=n;j++) if(ffa(j)==j) cnt++;
for(int j=;j<=nl;j++)
{
if(ffa(t[j].x)!=ffa(t[j].y))
{
fa[ffa(t[j].x)]=ffa(t[j].y);
now+=t[j].c;
cnt--;
}
if(cnt==) break;
}
ans=mymin(ans,now);
}
printf("%d\n",ans);
} int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&q);
for(int i=;i<=q;i++)
{
scanf("%d%d",&a[i][],&c[i]);
for(int j=;j<=a[i][];j++) scanf("%d",&a[i][j]);
}
for(int i=;i<=n;i++)
{
scanf("%d%d",&nx[i],&ny[i]);
}
len=;
for(int i=;i<=n;i++)
for(int j=i+;j<=n;j++)
{
// double xx=(double)(nx[i]-nx[j]),yy=(double)(ny[i]-ny[j]);
int xx=nx[i]-nx[j],yy=ny[i]-ny[j];
ins(i,j,xx*xx+yy*yy);
}
sort(t+,t++len,cmp);
int cnt=;nl=;
for(int i=;i<=n;i++) fa[i]=i;
for(int i=;i<=len;i++)
{
if(ffa(t[i].x)!=ffa(t[i].y))
{
fa[ffa(t[i].x)]=ffa(t[i].y);
cnt++;
t[++nl]=t[i];
}
if(cnt==n-) break;
}
ffind();
if(T) printf("\n");
}
return ;
}

- -

其实我觉得不用也没什么??反正都排序选前面的,区别??

 #include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
#define Maxn 1010
#define INF 0xfffffff int a[][Maxn],c[];
int nx[Maxn],ny[Maxn];
int n,q; struct node
{
int x,y,c;
}t[Maxn*Maxn];
int len,nl; void ins(int x,int y,int c)
{
t[++len].x=x;t[len].y=y;t[len].c=c;
} bool cmp(node x,node y) {return x.c<y.c;} int mymin(int x,int y) {return x<y?x:y;}
int mymax(int x,int y) {return x>y?x:y;} int fa[Maxn];
int ffa(int x)
{
if(fa[x]!=x) fa[x]=ffa(fa[x]);
return fa[x];
} void ffind()
{
int ans=INF;
for(int i=;i<(<<q);i++)
{
int now=;
for(int j=;j<=n;j++) fa[j]=j;
int ft=-;
for(int j=;j<=q;j++) if((<<j-)&i)
{
for(int k=;k<=a[j][];k++)
fa[ffa(a[j][k])]=ffa(a[j][]);
now+=c[j];
}
int cnt=;
for(int j=;j<=n;j++) if(ffa(j)==j) cnt++;
for(int j=;j<=len;j++)
{
if(ffa(t[j].x)!=ffa(t[j].y))
{
fa[ffa(t[j].x)]=ffa(t[j].y);
now+=t[j].c;
cnt--;
}
if(cnt==) break;
}
ans=mymin(ans,now);
}
printf("%d\n",ans);
} int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&q);
for(int i=;i<=q;i++)
{
scanf("%d%d",&a[i][],&c[i]);
for(int j=;j<=a[i][];j++) scanf("%d",&a[i][j]);
}
for(int i=;i<=n;i++)
{
scanf("%d%d",&nx[i],&ny[i]);
}
len=;
for(int i=;i<=n;i++)
for(int j=i+;j<=n;j++)
{
// double xx=(double)(nx[i]-nx[j]),yy=(double)(ny[i]-ny[j]);
int xx=nx[i]-nx[j],yy=ny[i]-ny[j];
ins(i,j,xx*xx+yy*yy);
}
sort(t+,t++len,cmp);
/*int cnt=0;nl=0;
for(int i=1;i<=n;i++) fa[i]=i;
for(int i=1;i<=len;i++)
{
if(ffa(t[i].x)!=ffa(t[i].y))
{
fa[ffa(t[i].x)]=ffa(t[i].y);
cnt++;
t[++nl]=t[i];
}
if(cnt==n-1) break;
}*/
ffind();
if(T) printf("\n");
}
return ;
}

像是没有区别= =

2016-11-01 22:24:10

【UVA 1151】 Buy or Build (有某些特别的东东的最小生成树)的更多相关文章

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

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

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

    链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...

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

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

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

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

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

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

  6. UVa 1151 Buy or Build (最小生成树+二进制法暴力求解)

    题意:给定n个点,你的任务是让它们都连通.你可以新建一些边,费用等于两点距离的平方(当然越小越好),另外还有几种“套餐”,可以购买,你购买的话,那么有些边就可以连接起来, 每个“套餐”,也是要花费的, ...

  7. UVa 1151 Buy or Build【最小生成树】

    题意:给出n个点的坐标,现在需要让这n个点连通,可以直接在点与点之间连边,花费为两点之间欧几里得距离的平方,也可以选购套餐,套餐中所含的点是相互连通的 问最少的花费 首先想kruskal算法中,被加入 ...

  8. UVA - 1151 Buy or Build (买还是建)(并查集+二进制枚举子集)

    题意:平面上有n个点(1<=n<=1000),你的任务是让所有n个点连通.可以新建边,费用等于两端点欧几里德距离的平方.也可以购买套餐(套餐中的点全部连通).问最小费用. 分析: 1.先将 ...

  9. UVA 1151 买还是建(最小生成树)

    买还是建 紫书P358 [题目链接]买还是建 [题目类型]最小生成树 &题解: 这题真的心累,看了3天,最后照着码还是wa,先放lrj代码,以后再看吧 &代码: // UVa1151 ...

  10. POJ(2784)Buy or Build

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

随机推荐

  1. Debian 6解决中文乱码

    DEBIAN下中文显示 一.首先检查LOCALE情况 说明:DEBIAN因为基于GNU所以,对不同地域进行了不同的包支持,以LOCALE形式存在. 1.挂载ISO文件包,前8个ISO包就可以(这里不在 ...

  2. Eclipse SVN插件账号、密码修改

    操作系统:win7 svn插件:Window -> Preferences -> Team -> SVN 修改方式: 1,删除C:\Users\用户名\AppData\Roaming ...

  3. sublime text 3快捷键设置

    sublime text 3  v-3103默认快捷键设置 [ { "keys": ["ctrl+shift+n"], "command": ...

  4. jquery - ul li click 无响应

    搞了很久, 发现对应jquery来说, 动态产生的ul li(其实不只是这个, 还有 table td等), 直接使用 $("#ul_div>li").click(funct ...

  5. SQL Server调优系列进阶篇 - 查询优化器的运行方式

    前言 前面我们的几篇文章介绍了一系列关于运算符的基础介绍,以及各个运算符的优化方式和技巧.其中涵盖:查看执行计划的方式.几种数据集常用的连接方式.联合运算符方式.并行运算符等一系列的我们常见的运算符. ...

  6. ASP和PHP限制IP访问 只允许指定IP访问 允许*号通配符过滤IP

    /** * 检测访问的ip是否为规定的允许的ip * Enter description here ... */ function check_ip(){ $ALLOWED_IP=array('192 ...

  7. [linux] 系统管理常用命令

    1.查看某个软件是否安装: rpm -qa|grep software_name 2.top命令,显示系统的动态视图,q退出 3.ps aux|grep process_name 显示正在运行的进程 ...

  8. uitableview的重用重叠问题

    以前也遇到过.但都不知道怎么就解决了. 今天费了一番功夫找到了最佳解决方案. 对于一些复杂的cell 从来都是用自定义的方法,但是如果复杂的cell里面内容多了.特别是图片加载,那难免会出现重叠重用 ...

  9. iOS .pch文件的使用

    什么是.pch文件预编译头文件(一般扩展名为.PCH),是把一个工程中较稳定的代码预先编译好放在一个文件(.PCH)里.这些预先编译好的代码可以是任何的C/C++代码--甚至可以是inline函数,只 ...

  10. Google Android SDK开发范例------------20141119

    一.Edit和Checkbox完成对登陆密码的查看:添加Edit的setOnCheckedChageListener和对CheckBox的状态通过isCHecked判断 大体代码如下 CheckBox ...