UVA 1151 Buy or Build 最小生成树+二进制选取子集
来源:互联网 发布:安卓优化提速吧 编辑:程序博客网 时间:2024/05/19 13:18
题目链接:点击打开链接
题意:给你n个点,你的任务是让这n个点连通。为此,你有两种方法,1、在某两点之间建边,费用为两点之间欧几里得距离的平方。2、购买一些套餐,当买了某个套餐后,套餐中的这些点将变得相互连通,问完成任务的最小费用是多少。
思路:先按全都不选套餐,求出此时的最小生成树,记录最小生成树的边,然后用套餐中的边来替换这些边。因为第一次求的那些边,肯定都是最优的,那些边恰好构成一棵最小生成树,不会再有比它小的了,购买套餐之后,结果就是,不仅以前求出的最优边还在里面,还会加入一些更优的边(权值为0)
#include<stdio.h>#include<string.h>#include<algorithm>#include<math.h>using namespace std;int a[10][1010],t[10],cost[10];int f[1010];struct p{ int x; int y; int z;} e[500100],vis[1010];bool cmp(p x,p y){ return x.z<y.z;}int getf(int v){ if(f[v]==v) return v; f[v]=getf(f[v]); return f[v];}int merge(int u,int v){ int t1=getf(u); int t2=getf(v); if(t1!=t2) { f[t1]=t2; return 1; } return 0;}int main(){ int T; int n,m; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); for(int i=0; i<m; i++) { scanf("%d%d",&t[i],&cost[i]); for(int j=0; j<t[i]; j++) scanf("%d",&a[i][j]); } int s1[1010],s2[1010]; for(int i=1; i<=n; i++) scanf("%d%d",&s1[i],&s2[i]); int sum=0; for(int i=1; i<=n; i++) { for(int j=i+1; j<=n; j++) { e[sum].x=i; e[sum].y=j; e[sum++].z=(s1[i]-s1[j])*(s1[i]-s1[j])+(s2[i]-s2[j])*(s2[i]-s2[j]);//两条边之间的花费 } } sort(e,e+sum,cmp); int k=0,cnt=0; for(int i=0; i<=n; i++) f[i]=i; int num=0; for(int i=0; i<sum; i++) { if(merge(e[i].x,e[i].y)) //不使用套餐找出最小生成树 { k+=e[i].z; cnt++; vis[num].x=e[i].x; vis[num].y=e[i].y; vis[num++].z=e[i].z;//记录使用了呢些边,使用套餐时在已经记录过的这里面选边,避免超时 } if(cnt==n-1) break; } for(int i=0; i<(1<<m); i++) { int k1=0,cnt=0; for(int j=0; j<=n; j++) f[j]=j; for(int j=0; j<m; j++) { if(i&(1<<j)) //二进制选子集,考虑用或不用该套餐的每种情况 { int u=a[j][0]; for(int f=1; f<t[j]; f++) { int v=a[j][f]; if(merge(u,v)) cnt++; } k1+=cost[j]; } } for(int j=0;j<num;j++) { if(merge(vis[j].x,vis[j].y)) { k1+=vis[j].z; cnt++; } if(cnt==n-1) break; } k=min(k,k1); } printf("%d\n",k); if(T) printf("\n"); } return 0;}
0 0
- UVA 1151 Buy or Build 最小生成树+二进制选取子集
- UVA 1151 - Buy or Build(最小生成树,二进制子集生成)
- uva-1151-Buy or Build-二进制枚举子集,并查集,最小生成树,kruskal
- UVa 1151 Buy or Build--最小生成树+二进制选择
- UVA 1151 Buy or Build(最小生成树+枚举子集)
- UVA 1151 && POJ 2784 - Buy or Build 最小生成树 二进制枚举
- UVA 1151 Buy or Build(生成树+二进制枚举)
- UVA1151[Buy or Build] 子集枚举+最小生成树
- uva 1151 Buy or Build (最小生成树)
- UVa 1151 Buy or Build (最小生成树)
- UVA 1151 Buy or Build (最小生成树)
- uva 1151 - Buy or Build poj 2784 Buy or Build(最小生成树)
- [最小生成树+二进制枚举]UVa1151 - Buy or Build
- UVA1511 Buy or Build 二进制枚举+最小生成树kruskal
- 【UVA】1151 - Buy or Build(二进制枚举子集 + 并查集)
- 买还是建buy or build,uva1151——最小生成树,Kruskal,枚举子集
- Uva1151.Buy or Build (最小生成树)
- 1151 - Buy or Build (最小生成树)
- Merge Intervals
- Java annotation入门
- spring中的设计模式
- [BZOJ1845][Cqoi2005] 三角形面积并(计算几何+扫描线)
- 深度学习算法实践14---去噪自动编码机(dA)的Theano实现
- UVA 1151 Buy or Build 最小生成树+二进制选取子集
- 对于Linux下的命令行参数,及环境变量存储问题探讨
- Android 截取手机屏幕两种实现方案解析
- STL向导阅读④-算法
- 解决kibana搜索提示框占位问题
- 获得文件的管理员权限
- 【安卓小笔记】应用基础知识
- getRealPath()和getContextPath()的区别
- CSS3--calc()