hdu oj 1233 最小生成树 采用Prim算法
2014-04-16 14:49
417 查看
#include <stdio.h> #include <string.h> //随后的N(N-1)/2行对应村庄间的距离,每行给出一对正整数 //这里可以看出这是一个完全无向连通图 //很明显采用最小生成树解决 //这里采用邻接矩阵来存储 #define NMAX 100 #define NMIN 0xfffff //主要是学习图数据结构,存储的时候还是定义规范点 typedef struct { int no; int info; }VertexType; //这个用来存储定点的信息的 typedef struct { int edges[NMAX][NMAX]; int n,e; //VertexType vxs[NMAX]; //存放定点的信息 //这里用不到 }MGrap; //采用prim最小生成树算法 int Prim(MGrap g,int v) { int res = 0;//记录所有边的和 int closest[NMAX]; //存储的是已经在最小生成树中的点 int lowcost [NMAX]; //存储的是closest中点对应其他点的边的距离 int m,i,flag,j;//flag用与标记找到的点 for(i=1;i<=g.n;i++) { closest[i] = v; //其实这里存储的就是(v,i)这条边,只是这条边的长度保存在lowcost中 lowcost[i] = g.edges[v][i]; //这里初始化(v,i)边距离 } for(i=1;i<g.n;i++)//找出剩余的n-1个点 { m=NMIN; for (j=1;j<=g.n;j++) { if(lowcost[j]!=0&&lowcost[j]<m) { m = lowcost[j]; flag = j; } } //将该条边的值加到res中 res+=m; lowcost[flag] = 0; //将找到的定点加入到定点集中 for(j=1;j<=g.n;j++) { //如果刚加入的点和其他点的边的长度所构成的候选边小于前面的候选边且不等于0 //那么将改变改为候选边,删除原来那条候选边 if(g.edges[flag][j]<lowcost[j]&&g.edges[flag][j]!=0) { closest[j] = flag; //修改边 lowcost[j] = g.edges[flag][j];//修改候选边对应的长度 } } } return res; } int main() { int n,x,y,val,i; MGrap g; while (scanf("%d",&n)&&n) { memset(g.edges,NMIN,sizeof(g.edges)); g.n = n; g.e = n*(n-1)/2; for (i=1;i<=n*(n-1)/2;i++) { scanf("%d %d %d",&x,&y,&val); g.edges[x][y] = val; g.edges[y][x] = val; if(i<=n) { g.edges[i][i]=0; //自己到自己为0 } } printf("%d\n",Prim(g,1)); } return 0; }
对应的PHP实现Prim 代码(写的有点简单):
<?php define("MAX",100); define('MIN', 0xffffff); //定义图 class MGrap { public $n=0; public $e=0; public $edges = array(array()); } function Prim(MGrap $g,$v) { $closest = array(); $lowcost = array(); $res = 0; for($i=1;$i<=$g->n;$i++) { $closest[$i] = $v; //初始化两个数组 $lowcost[$i] = $g->edges[$v][$i]; } $flag = -1; //标记当前找到的点 for($i=1;$i<$g->n;$i++) //找出剩下的n-1个点 { $min = MIN; for($j=1;$j<=$g->n;$j++) { if($lowcost[$j]<$min&&$lowcost[$j]!=0) { //找到对应的点 $flag = $j; $min = $lowcost[$j]; } } $lowcost[$flag] = 0 ;//将找到的顶点加入到树的集合中 $res+=$min; //修改数组 for($j=1;$j<=$g->n;$j++) { if($g->edges[$flag][$j]<$lowcost[$j]&&$g->edges[$flag][$j]!=0) { $lowcost[$j] = $g->edges[$flag][$j]; $closest[$j] = $flag; } } } return $res; } //这里只是为了测试直接初始化图 /* 4 1 2 1 1 3 4 1 4 1 2 3 3 2 4 2 3 4 5 输出5 */ $edg = array( 1=>array(2=>1,3=>4,4=>1), 2=>array(3=>3,4=>2), 3=>array(4=>5) ); var_dump($edg); $g = new MGrap(); $n = 4; //4个顶点 for($i=1;$i<=$n;$i++) { for($j=1;$j<=$n;$j++) { if(isset($edg[$i][$j])&&$edg[$i][$j]!=0) { $g->edges[$i][$j] = $edg[$i][$j]; $g->edges[$j][$i] = $edg[$i][$j]; } if($i==$j) { $g->edges[$j][$i] = 0; } } } $g->n = $n; $g->e = $n*($n-1)/2; var_dump($g); var_dump(Prim($g, 1)); ?>
相关文章推荐
- HDU 1233.还是畅通工程【最小生成树 kruskal算法(并查集)+prim算法】【1月8】
- 最小生成树prim算法实现及1233解题思路
- hdu 1233 还是畅通工程 最小生成树(prim算法 + kruskal算法)
- HDU-1233 最小生成树 Prim算法
- HDU-1233 还是畅通工程(最小生成树Prim算法)
- hdu 1233 还是畅通工程(最小生成树的Prim和Kruskal两种算法的c++实现)(prim算法详解)
- POJ1233 Agri-Net(最小生成树,prim算法)
- hdu1233 采用kruskal的最小生成树
- hdu 1233还是畅通工程 最小生成树(入门题)prim算法
- hdu 1233 还是畅通工程 最小生成树(prim算法 + kruskal算法)
- 最小生成树Prim算法实现(采用邻接表存储)C++实现
- HDU 1233 简单最小生成树 prim算法
- HDU 1233 还是畅通工程 最小生成树Kruskal算法和prim算法
- HDU 1233-还是畅通工程(经典的最小生成树, Kruskal和prim算法)
- hdu-1233-还是畅通工程(最小生成树,prim算法)
- HDU-1233 还是畅通工程(最小生成树 prim算法)
- hdu 1233 还是畅通工程(最小生成树的Prim和Kruskal两种算法的c++实现)(prim算法详解)
- Prim算法,最小生成树 HDU 1233
- 最小生成树Prim算法实现(采用邻接表存储)C++实现
- hdu 1233 最小生成树Prim算法