最小生成树的简单例题
来源:互联网 发布:星目读屏软件 编辑:程序博客网 时间:2024/06/05 02:04
**
灌溉(最小生成树)
**
到了旱季农业生产的灌溉就成了一个大问题。为了保证灌溉的顺利,某县政府决定投资为各个村之间建立灌溉管道。
输入第1行包括一个整数N,表示某县的村庄的数量。(3≤N≤100),第2行-结尾为一个N×N的矩阵,表示每个村庄之间的距离。虽然在理论上,他们是N行,每行由N个用空格分隔的数组成,实际上,他们限制在80个字符,因此,某些行会紧接着另一些行。当然,对角线将会是0,因为不会有线路从第i个村到它本身(任何两个村之间的距离都不大于100000)。
输出只有一个,为修建灌溉管道将所有村庄相连在一个灌溉系统里所需的最小管道长度。
样例输入
4
0 4 9 21
4 0 8 17
9 8 0 16
21 17 16 0
样例输出
28
第一种方法:Kruskal算法(用并查集做)
#include<iostream>#include<memory.h>#include<algorithm>#include<stdio.h>using namespace std;const int INF=99999;int per[20000];bool tag[20000];struct Edge{ int u; int v; int w;};Edge E[20000];int Find(int x){ int r=x; while(r!=per[r]) { r=per[r]; //找x的最终根节点 } int i=x,j; while(per[i]!=r) //把x->到根节点过程中的直接或所有间接根节点的根节点, { //都改为以r为直接根节点 j=per[i]; per[i]=r; i=j; } return r;}void join(int a,int b){ int Fx=Find(a),Fy=Find(b); if(Fx!=Fy) { per[Fy]=Fx; }}bool compare(Edge a,Edge b){ return a.w<b.w?true:false;}int main(){ int n; scanf("%d",&n); for(int i=0;i<n;i++) { per[i]=i; } int cost,k=0; for(int i=0;i<n;i++) { for(int j=0;j<n;j++) { scanf("%d",&cost); E[k].u=i; E[k].v=j; E[k].w=cost; k++; } } sort(E,E+k,compare); int e_number=0,min_cost=0; for(int i=0;i<k;i++) { if(Find(E[i].u)!=Find(E[i].v))//新找到的最小边的两个节点, { //如果根不同,连接他们不会有回路 join(E[i].u,E[i].v); e_number++; min_cost+=E[i].w; } if(e_number==n-1) { break; } } printf("%d\n",min_cost); return 0;}
第二种方法:Prim算法(不断更新lowcost数组)
#include<stdio.h>#include<iostream>#include<algorithm>using namespace std;const int INF=999999;const int MAX=105;const int MAX2=10005;int path[MAX][MAX];int tag[MAX2];int lowcost[MAX2];int main(){ int n; int min_cost=0,minn; //min_cost:最小边权值和 minn:最小边的权值 scanf("%d",&n); for(int i=0;i<n;i++) { for(int j=0;j<n;j++) { scanf("%d",&path[i][j]); } } for(int i=0;i<n;i++) { lowcost[i]=path[0][i]; } tag[0]=1; for(int i=0;i<n-1;i++) //这一层循环的i只是代表,共执行n-1次。 { minn=INF; int next; for(int j=0;j<n;j++) { if(tag[j]==0&&minn>lowcost[j])//每次i循环找出一条最小边 { minn=lowcost[j]; next=j; } } tag[next]=1; min_cost+=minn; for(int j=0;j<n;j++) //不断更新lowcost数组,以便下次i循环选择下条边 { if(tag[j]==0&&(lowcost[j]>path[next][j])) { lowcost[j]=path[next][j]; } } } printf("%d\n",min_cost); return 0;}
阅读全文
0 0
- 最小生成树的简单例题
- 最小生成树例题
- hdu 1233 (最小生成树 简单例题)
- 【普里姆算法】最小生成树-例题
- 最小生成树例题及其总结
- 例题11-2 UVA - 1395 Slim Span 苗条的生成树(Kruscal最小生成树)
- 简单最小生成树
- 简单的最小生成树1078
- 最小生成树 - kruskal 小讲 【 理解 + 例题 】
- 最小生成树 - prim 小讲 【 理解 + 例题 】 更新 ing...
- 最小生成树——(性质)其最大边权为生成树中最大边权最小的——(例题)承包池塘的青蛙
- POJ1258简单最小生成树
- POJ 1258Agri-Net 简单的最小生成树
- 003-普利姆算法求解最小生成树的简单实例
- 最小函数依赖的例题
- 某Trie树的简单例题
- 简单的触发器例题
- 第三章例题 最小生成元——逐位的写法
- 策略和装饰模式讲解
- 从三个角度分析:小程序可以直接打开网页的意义在哪?
- 属性动画完成控件拉宽
- 知道这20个正则表达式,能让你少写1,000行代码
- css之felxBox
- 最小生成树的简单例题
- Shell和Jenkins讲解
- 查询文章的上下篇Sql语句
- JUnit4 与 JMock 之双剑合璧-4
- jdk 1.7 hashMap源码解读
- numpy的getA()/getA1()/getH()/getI()函数
- 下联网关国标对接中的通信过程分析和实例之客户端主动发起的实时音视频点播过程
- div盒子模型
- 设计模式——单例模式