最小生成树练习1(克鲁斯卡尔算法Kruskal)
今天刷一下水题练手入门,明天继续。
poj1861 Network(最小生成树)新手入门题。
题意:输出连接方案中最长的单根网线长度(必须使这个值是所有方案中最小的),然后输出方案。
题解:本题没有直接求生成树,但如果连接n个集线器的方案多于n-1条边,那么必存在回路,因此去掉某些边剩下的边和所有顶点构成一个生成树。对于一个图的最小生成树来说,它的最大边满足所有生成树的最大边里最小,正和题意。
吐槽:题目样例是错的。。。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 const int N=1001; 6 struct edge{ 7 int u,v,w; 8 }e[15001]; 9 int f[N],a[N],ai; 10 int n,m,ma; 11 int cmp(edge a,edge b){ 12 return a.w<b.w; 13 } 14 void init(){ 15 for(int i=1;i<=n;++i) 16 f[i]=i; 17 } 18 int fin(int x){ 19 if(x!=f[x])f[x]=fin(f[x]); 20 return f[x]; 21 } 22 void Kruskal(){ 23 ma=ai=0; 24 int u,v,i; 25 init(); 26 for(i=0;i<m;++i){ 27 u=e[i].u; 28 v=e[i].v; 29 if((u=fin(u))!=(v=fin(v))){ 30 f[u]=v; 31 a[ai++]=i; 32 ma=max(e[i].w,ma); 33 } 34 if(ai>=n-1)break; 35 } 36 } 37 int main(){ 38 int i,u,v,w; 39 scanf("%d%d",&n,&m); 40 for(i=0;i<m;++i){ 41 scanf("%d%d%d",&u,&v,&w); 42 e[i]=edge{u,v,w}; 43 } 44 sort(e,e+m,cmp); 45 Kruskal(); 46 printf("%d\n%d\n",ma,ai); 47 for(i=0;i<ai;++i) 48 printf("%d %d\n",e[a[i]].u,e[a[i]].v); 49 return 0; 50 }
View Code
poj1251 Jungle Roads(最小生成树)水题。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 const int N=27; 6 struct edge{ 7 int u,v,w; 8 }e[75]; 9 int f[N]; 10 int n,m,ans; 11 int cmp(edge a,edge b){ 12 return a.w<b.w; 13 } 14 void init(){ 15 for(int i=0;i<n;++i) 16 f[i]=i; 17 } 18 int fin(int x){ 19 if(x!=f[x])f[x]=fin(f[x]); 20 return f[x]; 21 } 22 void Kruskal(){ 23 ans=0; 24 int u,v,i; 25 init(); 26 for(i=0;i<m;++i){ 27 u=e[i].u; 28 v=e[i].v; 29 if((u=fin(u))!=(v=fin(v))){ 30 f[u]=v; 31 ans+=e[i].w; 32 } 33 } 34 } 35 int main(){ 36 int i,j,w,k; 37 char u[3],v[3]; 38 while(scanf("%d",&n),n){ 39 m=0; 40 for(i=0;i<n-1;++i){ 41 scanf("%s %d",u,&k); 42 for(j=0;j<k;++j){ 43 scanf("%s %d",v,&w); 44 e[m++]={u[0]-'A',v[0]-'A',w}; 45 } 46 } 47 sort(e,e+m,cmp); 48 Kruskal(); 49 printf("%d\n",ans); 50 } 51 return 0; 52 }
View Code
poj1287 Networking(最小生成树)水题。
用prim要注意两个地点之间的线路可能多条,即有重边。我这里练的是Kruskal,题目没给边数,但知道点数最多50,则边数最多50*49/2=1225条,有重边,开大点数组就行,因为数据弱,随便开个1500都过了,醉。。。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 const int M=1500; 6 struct edge{ 7 int u,v,w; 8 }e[M]; 9 int f[50]; 10 int n,m,ans; 11 int cmp(edge a,edge b){ 12 return a.w<b.w; 13 } 14 void init(){ 15 for(int i=1;i<=n;++i) 16 f[i]=i; 17 } 18 int fin(int x){ 19 if(x!=f[x])f[x]=fin(f[x]); 20 return f[x]; 21 } 22 void Kruskal(){ 23 ans=0; 24 int u,v,i; 25 init(); 26 for(i=0;i<m;++i){ 27 u=e[i].u; 28 v=e[i].v; 29 if((u=fin(u))!=(v=fin(v))){ 30 f[u]=v; 31 ans+=e[i].w; 32 } 33 } 34 } 35 int main(){ 36 int i,u,v,w; 37 while(scanf("%d",&n),n){ 38 scanf("%d",&m); 39 for(i=0;i<m;++i){ 40 scanf("%d%d%d",&u,&v,&w); 41 e[i]={u,v,w}; 42 } 43 sort(e,e+m,cmp); 44 Kruskal(); 45 printf("%d\n",ans); 46 } 47 return 0; 48 }
View Code
poj2031 Building a Space Station(最小生成树)题目看老久,其实挺水…空间站存在一些球形单间,如果单间之间接触,重叠或用走廊连接则连通。给出单间坐标和半径,求要使得所有单间相连通的走廊总长度的最小值。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<cmath> 5 using namespace std; 6 const int M=5000; 7 const int N=100; 8 struct edge{ 9 int u,v; 10 double w; 11 }e[M]; 12 double a[N],b[N],c[N],r[N]; 13 int f[N]; 14 int n,m; 15 double ans; 16 int cmp(edge a,edge b){ 17 return a.w<b.w; 18 } 19 double dist(int i,int j){ 20 return sqrt((a[i]-a[j])*(a[i]-a[j])+(b[i]-b[j])*(b[i]-b[j])+(c[i]-c[j])*(c[i]-c[j]))-r[i]-r[j]; 21 } 22 void init(){ 23 for(int i=0;i<n;++i) f[i]=i; 24 } 25 int fin(int x){ 26 if(x!=f[x])f[x]=fin(f[x]); 27 return f[x]; 28 } 29 void Kruskal(){ 30 ans=0; 31 int u,v,i,cnt=0; 32 init(); 33 for(i=0;cnt<n-1;++i){ 34 u=e[i].u; 35 v=e[i].v; 36 if((u=fin(u))!=(v=fin(v))){ 37 f[u]=v; 38 ans+=e[i].w; 39 cnt++; 40 } 41 } 42 } 43 int main(){ 44 int i,j; 45 double w; 46 while(scanf("%d",&n),n){ 47 for(i=0;i<n;++i){ 48 scanf("%lf%lf%lf%lf",&a[i],&b[i],&c[i],&r[i]); 49 } 50 for(m=i=0;i<n-1;++i){ 51 for(j=i+1;j<n;++j){ 52 w=dist(i,j); 53 if(w<0) w=0; 54 e[m++]={i,j,w}; 55 } 56 } 57 sort(e,e+m,cmp); 58 Kruskal(); 59 printf("%.3f\n",ans); 60 } 61 return 0; 62 }
View Code
poj2421 Constructing Roads(最小生成树)水题。有些点已经连边,进行标记,加边时将其边赋值为0即可。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 const int M=5000; 6 const int N=101; 7 struct edge{ 8 int u,v,w; 9 }e[M]; 10 int f[N]; 11 int g[N][N],vis[N][N]; 12 int n,ans; 13 int cmp(edge a,edge b){ 14 return a.w<b.w; 15 } 16 void init(){ 17 for(int i=1;i<=n;++i) f[i]=i; 18 } 19 int fin(int x){ 20 if(x!=f[x])f[x]=fin(f[x]); 21 return f[x]; 22 } 23 void Kruskal(){ 24 ans=0; 25 int u,v,i,cnt=0; 26 init(); 27 for(i=0;cnt<n-1;++i){ 28 u=e[i].u; 29 v=e[i].v; 30 if((u=fin(u))!=(v=fin(v))){ 31 f[u]=v; 32 ans+=e[i].w; 33 cnt++; 34 } 35 } 36 } 37 int main(){ 38 int i,j,a,b,ei,m; 39 while(scanf("%d",&n)==1){ 40 for(i=1;i<=n;++i) 41 for(j=1;j<=n;++j) 42 scanf("%d",&g[i][j]); 43 memset(vis,0,sizeof(vis)); 44 scanf("%d",&m); 45 while(m--){ 46 scanf("%d%d",&a,&b); 47 vis[a][b]=1; 48 } 49 ei=0; 50 for(i=1;i<n;++i){ 51 for(j=i+1;j<=n;++j){ 52 if(vis[i][j]) e[ei++]={i,j,0}; 53 else e[ei++]={i,j,g[i][j]}; 54 } 55 } 56 sort(e,e+ei,cmp); 57 Kruskal(); 58 printf("%d\n",ans); 59 } 60 return 0; 61 }
View Code
转载于:https://www.cnblogs.com/GraceSkyer/p/5774634.html
最小生成树练习1(克鲁斯卡尔算法Kruskal)相关推荐
- 无向图的最小生成树(克鲁斯卡尔算法 Kruskal)
引子: 克鲁斯卡尔算法的作用是:构建图的最小生成树. 克鲁斯卡尔算法 Kruskal的构造过程: 1.初始化图:n个顶点,n个连通分量(如果两个顶点的连通分量相同,表示两点在同一个连通图中).把所有的 ...
- 贪心算法(Greedy Algorithm)最小生成树 克鲁斯卡尔算法(Kruskal#39;s algorithm)
克鲁斯卡尔算法(Kruskal's algorithm)它既是古典最低的一个简单的了解生成树算法. 这充分反映了这一点贪心算法的精髓.该方法可以通常的图被表示.图选择这里借用Wikipedia在.非常 ...
- Java普利姆算法(Prim)与克鲁斯卡尔算法(Kruskal)
1.Java普利姆算法(Prim)与克鲁斯卡尔算法(Kruskal) 普利姆算法(Prim)与克鲁斯卡尔算法(Kruskal)求**最小生成树(极小连通子图)**的算法 1.1普利姆算法(Prim) ...
- 数据结构——最小生成树之克鲁斯卡尔算法(Kruskal)
最小生成树算法 prime算法和克鲁斯卡尔算法 克鲁斯卡尔算法 思路 优先队列+并查集 Kuskal算法 [算法简介]:上一篇中的Prime算法是一种"加点式的算法",而Kuska ...
- prim算法求最小生成树_克鲁斯卡尔算法(Kruskal算法)求最小生成树
上一节介绍了求最小生成树之普里姆算法.该算法从顶点的角度为出发点,时间复杂度为O(n2),更适合与解决边的绸密度更高的连通网.本节所介绍的克鲁斯卡尔算法,从边的角度求网的最小生成树,时间复杂度为O(e ...
- 数据结构与算法-克鲁斯卡尔算法(Kruskal) | 尚硅谷韩顺平
提出问题 基本介绍 克鲁斯卡尔(Kruskal)算法,求加权连通图最小生成树的算法 基本思想:按权值从小到大顺序选择n-1条边,保证n-1条边不够成回路 具体做法:先构造一个只有n顶点的森林,然后按权 ...
- kruskal算法java_克鲁斯卡尔算法(Kruskal)的java实现
下面是我对软件工程教程里面的克鲁斯卡尔算法的实现,发现在网是很少有网友贴出,为了方便大家查询,所以贴出来了,还希望大家能多指点. package Test; import java.io.Buffer ...
- 最小生成树:克鲁斯卡尔算法+普里姆算法
目录 一.最小生成树 二.克鲁斯卡尔算法 1.思路 2.示例 3.C语言代码 三.普里姆算法 1.思路 2.C语言代码 一.最小生成树 一棵最小生成树需要满足哪些条件呢? 不存在回路 对于具有n个顶点 ...
- 大话数据结构-普里姆算法(Prim)和克鲁斯卡尔算法(Kruskal)
5 最小生成树 构造连通网的最小代价生成树称为最小生成树,即Minimum Cost Spanning Tree,最小生成树通常是基于无向网/有向网构造的. 找连通网的最小生成树,经典的有两种 ...
最新文章
- 2022-2028年中国密胺塑料制品行业市场研究及前瞻分析报告
- RedisClient 连接redis 提示 ERR Client sent AUTH, but no password is set
- linux pppd源码下载_pppd源代码分析
- 再见DTC,你好Christmas Day
- 专题_数字货币历史行情获取[博]
- D3D学习摘记(I)上
- 用sql写每年的第三周_如何写好5000行的SQL代码
- js调用Bartender
- 【Android容器组件—AdapterView】
- 汉字排序法(汉字转拼音)
- conan入门(十九):封装第三方开源库cpp_redis示例
- 如何一键重装电脑系统?在家里用电脑重装win10系统步骤
- 李航 《统计学习方法》习题8.1
- android 闪屏图片,Android的闪屏图像尺寸,以适应所有设备Android的闪屏图像尺寸,以适应所有设备(Andro...
- pscc2018安装服务器无响应,一招解决PSCC2018无法安装扩展插件
- 红米电竞路由器AX5400与红米路由器AX5400哪个值得买? 两者区别介绍
- 1U,2U,3U,4U机箱面板,U的含义
- 基于vue+el-upload图片上传(自用屎山)
- 怎么清理计算机里的音乐,如何清理电脑中的重复的音乐
- 第917期机器学习日报(2017-03-23)