HDU 1875 最小生成树prim算法
2016-02-27 10:52
316 查看
#include<iostream> #include<cstdio> #include<algorithm> #include<cmath> #include<cstring> #define MAX 0xffffffff //定义一个最小生成树中不可能达到的值 const int qq=100+10; // 点的上限 using namespace std; struct point{ int x,y; }node[qq]; double lowcost[qq][qq]; // 邻接矩阵 int vis[qq]; // 最小生成树的点集合vis数组 int n; double f(point a,point b) { return sqrt(pow(a.x-b.x,2.0)+pow(a.y-b.y,2.0)); } void build() { double len; for(int j,i=0;i<n;++i) for(j=i;j<n;++j){ len=f(node[i],node[j]); // 计算两点之间的距离也就是点与点的权值、 if(len>=10&&len<=1000) lowcost[i][j]=lowcost[j][i]=(i==j)?0:len; else lowcost[i][j]=lowcost[j][i]=MAX; // 值为MAX 意味着这两点不连通、 } } void prim() { int k,t=n; double min,tot=0; vis[0]=0; //初始点0进入最小生成树数组中、 while(--t){ min=MAX; for(int i=1;i<n;++i){ if(vis[i]!=0&&lowcost[0][i]<min){ //lowcost[0]代表当前的最小生成树的最小权值数组、 min=lowcost[0][i]; //找到当前最小的权值并记录是哪一个点、 k=i; } } if(min==MAX) break; //如果最小权值都为MAX 也就是不连通也可以跳出循环了、 vis[k]=0; // 点k进入最小生成树数组、 tot+=min; //统计权值、 for(int i=1;i<n;++i) //因为加入了一个点到最小生成树中,所以要更新当前的最小权值数组、 if(vis[i]!=0&&lowcost[k][i]<lowcost[0][i]) lowcost[0][i]=lowcost[k][i]; } if(t==0) printf("%.1f\n",tot*100); else printf("oh!\n"); } int main() { int t;cin >> t; while(t--){ memset(vis,1,sizeof(vis)); //清空标记数组、 scanf("%d",&n); for(int i=0;i<n;++i) scanf("%d%d",&node[i].x,&node[i].y); build(); prim(); } }
刚做这题我模型没转换过来,以为只要把横坐标按从小到大排序,横坐标相同就按纵坐标从小到大排序然后然后从左到右从下道上连接各点就是最小生成树、
- - 、 错的太离谱了,代码就不拿出来丢脸了
题目设置的限制条件实际上就是不连通,这点想通了就好做了
相关文章推荐
- html-label标签
- [自定义组件之二]两种方式改造UIView
- 简单工厂模式
- 多线程socket编程--聊天程序
- 1046 Shortest Distance
- Test...
- [数据结构]Phone-Number Manager
- spark-shell和scala错误
- RPC乱序
- 计算机网络15--网络应用对传输服务的需求
- 基于dubbo框架下的RPC通讯协议性能测试
- Android DownloadManager 的使用
- POJ1463(树形DP)
- spark-shell和scala错误
- 【leetcode】【9】Palindrome Number
- sql 日期 增加2个月
- Android概念(持续整理)
- 进程与线程的一个简单解释
- MySQL中EXPLAIN解释命
- 169. Majority Element My Submissions Question