Kruskal算法例题
来源:互联网 发布:中美军事差距知乎 编辑:程序博客网 时间:2024/06/03 03:40
例题一:剑鱼行动(Swordfish).
题目描述:给定平面上N个城市的坐标,计算连接这n个城市所需线路长度的最小值。
输出描述:如下图所示,每两个测试数据的输出之间输出一个空行
#include<cstdio>#include<cstring>#include<iostream>#include<cmath>#include<stdlib.h>using namespace std;#define MAXN 110#define MAXM 5000struct edge{ int u,v; double w;}edges[MAXN];int parent[MAXN];int n,m;double x[MAXN],y[MAXN];///每个顶点x坐标和y坐标int i,j;double sumweight;void UFset(){ for(i=0;i<n;i++) parent[i]=-1;}int Find(int x){ int s; for(s=x;parent[s]>=0;s=parent[s]); while(s!=x)///压缩路径 { int temp=parent[x]; parent[x]=s; x=temp; } return s;}void Union(int R1,int R2){ int r1=Find(R1); int r2=Find(R2); int temp=parent[r1]+parent[r2]; if(parent[r1]>parent[r2])///加权法则 { parent[r1]=r2; parent[r2]=temp; } else { parent[r2]=r1; parent[r1]=temp; } } int cmp(const void *a,const void *b) { edge aa=*(const edge *)a; edge bb=*(const edge *)b; if(aa.w>bb.w) return 1; else return -1; } void Kruskal() { int num=0; int u,v; UFset(); for(i=0;i<m;i++) { u=edges[i].u; v=edges[i].v; if(Find(u)!=Find(v)) { sumweight+=edges[i].w; num++; Union(u,v); } if(num>=n-1) break; } } int main() { double d; int kase=1; while(scanf("%d",&n)!=EOF) { if(n==0) break; for(i=0;i<n;i++) scanf("%lf%lf",&x[i],&y[i]); int mi=0;///记录边的数目 for(i=0;i<n;i++)///任意两个顶点间的距离,有意思 for(j=i+1;j<n;j++) { d=sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j])); edges[mi].u=i; edges[mi].v=j; edges[mi].w=d; mi++; } m=mi; qsort(edges,m,sizeof(edges[0]),cmp);///快速排序 sumweight=0.0; Kruskal(); if(kase>1)///第一组测试数据前有空格 { printf("\n"); getchar(); } printf("Case #%d:\n",kase); printf("The minimum distance is: %0.2f\n",sumweight); kase++; } return 0; }
测试数据:
例题二:网络(Network)
先输入顶点和边,然后是每条边的起始点和边的权值
输出描述:首先输出最长的单根网线的长度。然后输出设计方案:先输入一个整数p,代表所使用的网线的数目,然后输出p对顶点,表示每对网线所连接的集线器的编号
#include<cstdio>#include<iostream>#include<cstring>#include<stdlib.h>using namespace std;#define MAXN 1005#define MAXM 15005struct edge{ int u,v,w; }edges[MAXM]; int parent[MAXN]; int ans[MAXN],ai;///存储的是依次选择的边的序号;数组ans的下标 int n,m; int num,maxedge;///最长的边 int i,j; void UFset() { for(i=0;i<n;i++) parent[i]=-1; } int find(int x) { int s=x; for(s=x;parent[s]>=0;s=parent[s]); while(s!=x)///压缩路径 { int temp=parent[x]; parent[x]=s; x=temp; } return s; } void Union(int R1,int R2) { int r1=find(R1); int r2=find(R2); int temp=parent[r1]+parent[r2]; if(parent[r1]>parent[r2])///加权法则 { parent[r1]=r2; parent[r2]=temp; } else { parent[r2]=r1; parent[r1]=temp; } } int cmp(const void *a,const void *b) { edge aa=*(const edge *)a; edge bb=*(const edge *)b; return aa.w-bb.w; } void Kruskal() { ai=0; num=0; maxedge=0; int u,v; UFset(); for(i=0;i<m;i++) { u=edges[i].u; v=edges[i].v; if(find(u)!=find(v)) { ans[ai]=i; ai++; if(edges[i].w>maxedge) maxedge=edges[i].w; num++; Union(u,v); } if(num>=n-1) break; } } int main() { int i,j; while(scanf("%d%d",&n,&m)!=EOF) { for(i=0;i<m;i++) scanf("%d%d%d",&edges[i].u,&edges[i].v,&edges[i].w); qsort(edges,m,sizeof(edges[0]),cmp); Kruskal(); printf("%d\n",maxedge); printf("%d\n",num); for(i=0;i<num;i++)///ans[]存储的是依次选择的边的序号 printf("%d %d\n",edges[ans[i]].u,edges[ans[i]].v); } return 0; }
0 0
- Kruskal算法例题
- 例题:最短网络 图论算法之最小生成树 prim//kruskal 学习笔记
- Kruskal算法
- Kruskal算法
- Kruskal算法
- kruskal算法
- Kruskal算法
- Kruskal算法
- Kruskal算法
- Kruskal算法
- kruskal算法
- kruskal算法
- kruskal算法
- Kruskal算法
- kruskal算法
- Kruskal算法
- Kruskal算法
- Kruskal算法
- 安装系统失败,多出来错误的系统引导项
- <Unity笔记>Camera.ScreenToWorldPoint 屏幕转世界位置
- 第9章 引用
- 快递小哥逆袭自传:用了6年时间做到了IT部门主管
- 夕拾算法进阶篇:29)深度搜索和广度搜索(图论)
- Kruskal算法例题
- 第10章 函数
- Java HashMap原理
- 如何在Linux中查找一个文件
- vue2.0 $refs的使用
- PAT 1046
- 1.4:被隐形的具体实现
- 算法研究:已知不重复的int集合,求最长递增子序列
- 面试代码