UVA 1151 生成树
来源:互联网 发布:老梁观世界 知乎 编辑:程序博客网 时间:2024/06/04 17:49
题意
要让N个点连通,可以选择购买套餐,也可以选择自己手动连接两个点。购买套餐的话,套餐内的所有点会相互连接。手动连接的话,费用为两个点之间欧几里得距离的平方。求最低费用。
题解
暴力枚举购买套餐情况,针对每一种情况,使用Kruskal算法计算最小生成树的费用。在暴力枚举之前,可以先使用一次Kruskal算法降低时间复杂度,因为最后形成的最小生成树一定是由不购买任何套餐情况下最小生成树的边与套餐包含的边组成的。
注意事项
注意结构体内int的值不确定,因此如果结构体数组内有元素没有赋值,就不要轻易sort,否则可能会导致结果错误。
代码
#include <iostream>#include<cstdio>#include<algorithm>#include<vector>#include<cstring>#define INF 1e9using namespace std;struct Node{ int x,y;};struct Edge{ int u,v,w;};Node no[1010];Edge ed[1000010];Edge newed[1100];vector<int> buy[10];int cost[10];int p[1010];int n,m;int con;int cmp(Edge e1,Edge e2){ return e1.w<e2.w;}int find(int x){ return x==p[x]?x:p[x]=find(p[x]);}int kruskal1(){ int num=0; int ans=0; for(int i=0;i<con;i++){ int a=find(ed[i].u); int b=find(ed[i].v); if(a!=b){ ans+=ed[i].w; newed[num].u=ed[i].u; newed[num].v=ed[i].v; newed[num++].w=ed[i].w; p[b]=a; if(num>=(n-1)) break; } } return ans;}int kruskal2(){ int ans=0; for(int i=0;i<n;i++){ int a=find(newed[i].u); int b=find(newed[i].v); if(a!=b){ p[b]=a; ans+=newed[i].w; } } return ans;}int main(){ int kase; scanf("%d",&kase); while(kase--){ for(int i=0;i<10;i++){ buy[i].clear(); } scanf("%d%d",&n,&m); for(int i=0;i<m;i++){ int num; scanf("%d%d",&num,&cost[i]); for(int j=0;j<num;j++){ int x; scanf("%d",&x); buy[i].push_back(x); } } for(int i=1;i<=n;i++){ scanf("%d%d",&no[i].x,&no[i].y); } con=0; for(int i=0;i<n;i++){ for(int j=i+1;j<n;j++){ ed[con].u=i+1; ed[con].v=j+1; ed[con++].w=(no[i+1].x-no[j+1].x)*(no[i+1].x-no[j+1].x)+(no[i+1].y-no[j+1].y)*(no[i+1].y-no[j+1].y); } } sort(ed,ed+con,cmp); for(int i=1;i<=n;i++){ p[i]=i; } int ans=kruskal1(); for(int i=0;i<(1<<m);i++){ int cos=0; for(int j=1;j<=n;j++){ p[j]=j; } for(int j=0;j<m;j++){ int s=i&(1<<j); if(s){ cos+=cost[j]; for(int k=0;k<buy[j].size()-1;k++){ int a=find(buy[j][k]); int b=find(buy[j][k+1]); if(a!=b) p[b]=a; } } } ans=min(ans,cos+kruskal2()); } if(kase) printf("%d\n\n",ans); else printf("%d\n",ans); } return 0;}
0 0
- UVA 1151 生成树
- uva 1151最小生成树
- UVA 1395 生成树
- UVA 10369 最小生成树
- uva 10397(最小生成树)
- uva 10034(最小生成树)
- uva 10369(最小生成树)
- uva 10766 生成树计数
- UVa 1395 最小生成树
- uva 10369 最小生成树
- uva 1151 Buy or Build (最小生成树)
- UVA 1151 Buy or Build(生成树+二进制枚举)
- 最小生成树,Kruskal(买还是建 uva 1151)
- UVa 1151 Buy or Build (最小生成树)
- UVa 1151 Buy or Build--最小生成树+二进制选择
- UVA 1151 Buy or Build (最小生成树)
- UVA 1151 - Buy or Build(最小生成树,二进制子集生成)
- uva 4138【最小生成树prime算法】
- http请求
- Mac系统终端命令行不执行命令 总出现command not found解决方法
- webpack配置环境变量解决“不是内部命令”问题
- 当你有一个想法时--POC
- java 前端乱码问题
- UVA 1151 生成树
- PowerDesigner使用教程
- Linux面试题集锦五
- 【环境】Caffe安装 'unique_path' is not a member of 'boost::filesystem' 问题解决
- 【从基础学 Java】序
- CCF CSP 编程题目和解答-----试题名称:权限查询-------201612-3
- 设计数据库及数据库的语句优化(mysql)
- CUDA编程实践-3
- 最小公倍数和最大公约数