下载此文档

最小生成树.并查集.最短路.ppt


文档分类:通信/电子 | 页数:约49页 举报非法文档有奖
1/49
下载提示
  • 1.该资料是网友上传的,本站提供全文预览,预览什么样,下载就什么样。
  • 2.下载该文档所得收入归上传者、原创者。
  • 3.下载的文档,不会出现我们的网址水印。
1/49 下载此文档
文档列表 文档介绍
最小生成树并查集最短路
罗方炜
lfw2565295@
最小生成树
问题描述:某省调查乡村交通状况,得到的统计表中列出了任意两村庄间的距离。省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可),并要求铺设的公路总长度为最小。请计算最小的公路总长度。
最小生成树
输入:测试输入包含若干测试用例。每个测试用例的第1行给出村庄数目N ( < 100 );随后的N(N-1)/2行对应村庄间的距离,每行给出一对正整数,分别是两个村庄的编号,以及此两村庄间的距离。为简单起见,村庄从1到N编号。 当N为0时,输入结束,该用例不被处理。 输出:对每个测试用例,在1行里输出最小的公路总长度。
最小生成树
样例输入:
3
1 2 1 1 3 2 2 3 4
4
1 2 1 1 3 4 1 4 1 2 3 3 2 4 2 3 4 5
0
样例输出:
3
5
最小生成树
最小生成树:在一个具有几个顶点的连通图G中,如果存在子图G‘包含G中所有顶点和一部分边,且不形成回路,则称G’为图G的生成树,代价最小生成树则称为最小生成树。简称MST。
最小生成树
一般有两种算法:Prim和Kruskal算法

今天主要讲Kruskal算法,适用本题,给出的边数,复杂度elong(e) (其中e表示变数)
最小生成树
算法粗略描述:假设 WN=(V,{E}) 是一个含有 n 个顶点的连通网,先构造一个只含 n 个顶点,而边集为空的子图,若将该子图中各个顶点看成是各棵树上的根结点,则它是一个含有 n 棵树的一个森林。之后,从网的边集 E 中选取一条权值最小的边,若该条边的两个顶点分属不同的树,则将其加入子图,也就是说,将这两个顶点分别所在的两棵树合成一棵树;反之,若该条边的两个顶点已落在同一棵树上,则不可取,而应该取下一条权值最小的边再试之。依次类推,直至森林中只有一棵树,也即子图中含有 n-1条边为止。
最小生成树
做法:
定义结点:
#define M 10005
struct node{
int x,y,w; //表示x到y需要花费w
}e[M];
int n,m,father[M]; //n定点数量,m边数量,father[M],每个定点所属集合
最小生成树
int kruskal(){
int res=0,k=1,j=0;
for(int i=1; i<=m; i++) father[i]=i; //初始化集合数组
while(k<n && j<m){ //需要n-1条边
int m1=e[j].x, m2=e[j].y;
int sn1=findroot(m1), sn2=findroot(m2);
I f(sn1!=sn2){
res+=e[j].w; k++; //生成数+1
unionset(sn1,sn2);
}j++;
}
if(k!=n) res=-1; //不可能的情况,产生不了最小生成树
return res;
}
最小生成树
int main(){
while(scanf("%d",&n) && n){
m=n*(n-1)/2;
for(int i=0; i<m; i++) scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].w);
sort(e,e+m,cmp);
//排序按边权w值从小到大排序
printf("%d\n",kruskal());
}
}

最小生成树.并查集.最短路 来自淘豆网m.daumloan.com转载请标明出处.

相关文档 更多>>
非法内容举报中心
文档信息
  • 页数49
  • 收藏数0 收藏
  • 顶次数0
  • 上传人nb6785
  • 文件大小0 KB
  • 时间2015-10-12
最近更新