SZUOJ-Problem(J16):Bright stars最小生成树
来源:互联网 发布:淘宝上的百度财富 编辑:程序博客网 时间:2024/06/14 05:58
问题来了:怎样才能在以最少虫洞的情况下,并且虫洞的长度总和最小,使一个时空星系中所有星球连接在一起?
Input
有许多组测试数据,每组测试数据中,第一行一个n(2<=n<=2000),表示某星系恒星的数量.
接下来n行,每行4个整型数据x,y,z,t(0<=x,y,z,t<=1000).表示恒星在宇宙中的空间坐标点以及时间的维度t(忽略计算恒星的体积大小)。
Output
输出1行,包含三个数字(用一个空格区分,注意最后一个数字后面没空格).
第一个是需要虫洞的数量,第二个是所有虫洞总长度之和(输出后4位小数).第三个是最长的虫洞的长度(输出后4位小数).
Sample Input
40 0 0 00 1 1 01 1 1 00 0 0 1
Sample Output
3 3.4142 1.4142
Hint
我们知道,1维 空间 上的距离d=x
我们知道,2维 空间 上的距离
我们知道,3维 空间 上的距离
类似地, 4维 时空 上的距离
Sample中 0 0 0 0,我们可以想象为是地球,而0 1 1 0是木星,1 1 1 0是金星,0 0 0 1是未来1个世纪后的地球。
还有的是,注意星球的数量有点多,大家注意处理。
代码1
prim算法
#include <cstdio>#include <cmath>#include <cstring>#include <string>#include <algorithm>#include <iostream>using namespace std;#define INF 0x7F800000int mtx[2005][5];int dist[2005];int getDist(int i,int j){int ret = (mtx[i][1]-mtx[j][1])*(mtx[i][1]-mtx[j][1])+(mtx[i][2]-mtx[j][2])*(mtx[i][2]-mtx[j][2])+(mtx[i][3]-mtx[j][3])*(mtx[i][3]-mtx[j][3])+(mtx[i][4]-mtx[j][4])*(mtx[i][4]-mtx[j][4]); return ret;}int main(){int t,n,i,j,k;while(scanf("%d",&n)!=EOF){ for (k=1;k<=n;k++)scanf("%d%d%d%d",&mtx[k][1],&mtx[k][2],&mtx[k][3],&mtx[k][4]);for (j=1;j<=n;j++) //创建第一组dist{ dist[j]=getDist(1,j);} double ans=0;double tmp=0;for (k=2;k<=n;k++) //不断更新dist{int minEdge=INF;int minpoint; // minEdge记录当前往外扩展的最小非零边权,minPoint记录对应边指向的节点编号for (j=1;j<=n;j++) //不断更新dist{if (dist[j]!=0 && dist[j]<minEdge) //找到最小加权边与点{minEdge=dist[j];minpoint=j;}}if (tmp<minEdge) tmp=minEdge;dist[minpoint]=0; //将当前节点标记为已加入生成树,dist值置零ans+=sqrt(minEdge); //累计生成树的路径长度for (j=1;j<=n;j++) ////用此节点一一跟新其他点的dist值{if ( getDist(minpoint,j)<dist[j] )dist[j]=(getDist(minpoint,j));} } printf("%d %.4lf %.4lf\n",n-1,ans,sqrt(tmp) );}return 0;}
代码2
克鲁斯卡尔算法
#include <cstdio>#include <cmath>#include <cstring>#include <string>#include <algorithm>#include <vector>#include <iostream>using namespace std;int g[2005];int f[2005][5]; int find(int x) //x所在集合的根{if(x==g[x]) return x;return g[x]=find(g[x]);} struct aaaa{int u,v;int weight;}; aaaa edge[2000003]; bool cmp(aaaa a,aaaa b) { return (a.weight<b.weight);} int main() { int t,n,i,j,k,pp,s,p;while(scanf("%d",&t)!=EOF){for (i=1;i<=t;i++){scanf("%d%d%d%d",&f[i][1],&f[i][2],&f[i][3],&f[i][4]);}for(int j=1;j<=t;j++) g[j]=j; //初始化为自己////////********************** int ko=1;for (j=1;j<=t;j++){for (k=j+1;k<=t;k++){edge[ko].u=j;edge[ko].v=k;edge[ko].weight= ( (f[j][1]-f[k][1])*(f[j][1]-f[k][1])+(f[j][2]-f[k][2])*(f[j][2]-f[k][2])+(f[j][3]-f[k][3])*(f[j][3]-f[k][3])+(f[j][4]-f[k][4])*(f[j][4]-f[k][4]) ); ko++; }} sort(edge+1,edge+ko,cmp); double z=0;int z1=0; doubletmp=edge[1].weight;for (j=1;j<=t*(t-1)/2;j++){ int sb=find( edge[j].v); //找根int sa=find( edge[j].u); //找根if ( sa!=sb ) { g[sb]=sa; if (edge[j].weight>tmp) tmp=edge[j].weight;z+=sqrt(edge[j].weight);z1++;if (z1>=(t-1)) break; } }printf("%d %.4lf %.4lf\n", z1,z,sqrt(tmp));} return 0;}
0 0
- SZUOJ-Problem(J16):Bright stars最小生成树
- SZUOJ-Problem(A60):Roads
- Problem 2195 检查站点【最小生成树】
- Problem(A18):Climb Well In SZUOJ青蛙爬井
- codeforces472D Design Tutorial: Inverse the Problem 最小生成树+dfs
- POJ Problem 2377 Cowtractors 【最小生成树Prim】
- POJ Problem 1258 Agri-Net 【最小生成树Prim】
- 2017年ZJUT校赛-Problem F: 最小生成树
- SDNU 1229.A math problem 最小生成树 prim算法
- 最小比例 最小生成树
- http://acm.nyist.net/JudgeOnline/problem.php?pid=38&&最小生成树
- CodeForces 472D Design Tutorial: Inverse the Problem (最小生成树)
- HDU Problem 1875 畅通工程再续 【最小生成树Prim】
- CodeForces 472D Design Tutorial: Inverse the Problem (最小生成树+lca)
- 最小生成树&&次最小生成树
- 最小生成生成树计数
- The Bug Sensor Problem 最小生成树求第k大边
- 树+最小生成树
- Alex 的 Hadoop 菜鸟教程: 第11课 Hive的Java调用
- 【设计模式】-装饰者模式(Wrapper)
- Maximum Prodyct Subarray Leetcode Python
- 倒计时
- 瞬间击中以至于改变了吾等的价值观的自然科学理论。
- SZUOJ-Problem(J16):Bright stars最小生成树
- POJ 3728 离线 LCA
- hdu-1003-Max Sum
- hdu-2050-折线分割平面
- hdu-2200-Eddy's AC难题
- 我的2014——典型程序员的一年,不想再重来
- 只要有心做,世界无难事情,好好加油吧
- Jacob 操作Word文档示例
- EventBus的初步使用和线程间的调用,已经一些相关安全的修饰词