题目描述

根据输入创建无向网。分别用Prim算法和Kruskal算法构建最小生成树。(假设:输入数据的最小生成树唯一。)

输入

顶点数n

n个顶点

边数m

m条边信息,格式为:顶点1 顶点2 权值

Prim算法的起点v

输出

输出最小生成树的权值之和

对两种算法,按树的生长顺序,输出边信息(Kruskal中边顶点按数组序号升序输出)

样例输入

6
v1 v2 v3 v4 v5 v6
10
v1 v2 6
v1 v3 1
v1 v4 5
v2 v3 5
v2 v5 3
v3 v4 5
v3 v5 6
v3 v6 4
v4 v6 2
v5 v6 6
v1

样例输出

15
prim:
v1 v3 1
v3 v6 4
v6 v4 2
v3 v2 5
v2 v5 3
kruskal:
v1 v3 1
v4 v6 2
v2 v5 3
v3 v6 4
v2 v3 5
 
 普里姆算法更新lowcost数组的值
#include<iostream>
using namespace std;
struct{
string adjvex;
int lowcost;
}closedge[];
class MGraph
{
public:
int graph[][],graph1[][];
int n,len; //n 是节点个数 len是边的数
int visited[],low[];
string *q;//存节点
string start;
int startpos;
MGraph(){};
void SetMGraph()
{
int i,j;
cin>>n;
for(i=;i<;i++)
for(j=;j<;j++)
{
graph[i][j]=; //将每个权值置为最大
graph1[i][j]=;
} q=new string[n];
for(i=;i<n;i++)
cin>>q[i];
cin>>len;
for(i=;i<=len;i++)
{
string ch1,ch2;
int weight;
cin>>ch1>>ch2>>weight;
int loc1,loc2;
for(j=;j<n;j++)
{
if(q[j]==ch1)
loc1=j;
if(q[j]==ch2)
loc2=j;
}
graph1[loc1][loc2]=graph[loc1][loc2]=weight;
graph1[loc1][loc2]=graph[loc2][loc1]=weight;//无向图
}
cin>>start;
for(i=;i<n;i++)
if(q[i]==start)
startpos=i;
}
void prim()
{
int i,j;
for(i=;i<=n;i++)
visited[i]=;
visited[startpos]=;
int min;
for(i=;i<n;i++)
{
min=;
for(j=;j<n;j++)
{
if(graph[i][j]<min)
{
min=graph[i][j];
closedge[i].adjvex=q[j];
closedge[i].lowcost=min;
}
}
}
string s3;
string *e1,*e2;
int *w3;
e1=new string[];
e2=new string[];
w3=new int[];
int index,k=;
for(i=;i<n;i++)
{
min=;
for(j=;j<n;j++)
{
if(!visited[j])
continue;
else
{
if(min>closedge[j].lowcost)
{
min=closedge[j].lowcost;
s3=closedge[j].adjvex;
index=j;
}
}
}
e1[k]=q[index];e2[k]=s3,w3[k++]=min;
for(int g=;g<n;g++)
{
if(q[g]==s3)
{
visited[g]=;
// graph[index][g]=99999;
// graph[g][index]=99999;
break;
}
}
for(int g=;g<n;g++)
{
min=;
for(int m=;m<n;m++)
{
if(min>graph[g][m] && visited[m]==)
{
min=graph[g][m];
closedge[g].adjvex=q[m];
closedge[g].lowcost=min;
}
}
}
}
int weight=;
for(i=;i<k-;i++)
{
weight+=w3[i];
}
cout<<weight<<endl;
cout<<"prim:"<<endl;
for(i=;i<k-;i++)
cout<<e1[i]<<" "<<e2[i]<<" "<<w3[i]<<endl;
}
void kruskal()
{
cout<<"kruskal:"<<endl;
int *uni=new int[n];
for(int i=;i<n;i++)
{
uni[i]=i;
}
for(int i=;i<n-;i++)
{
int min=;int x,y;
for(int j=;j<n;j++)
{
for(int l=;l<n;l++)
{
if(j==l)
continue;
if(uni[j]==uni[l])
continue;
else
{
if(min>graph1[j][l])
{
min=graph1[j][l];
x=j;y=l;
} }
}
}
graph1[x][y]=;graph1[y][x]=;
if(x>y)
int k;k=x;x=y;y=k; for(int i=;i<n;i++)
{
if(uni[i]==uni[y]&&i!=y) uni[i]=uni[x];
}
uni[y]=uni[x];
cout<<q[x]<<" "<<q[y]<<" "<<min<<endl;
}
}
void show()
{
int i,j;
for(i=;i<n;i++)
{
for(j=;j<n;j++)
cout<<graph[i][j]<<" ";
cout<<endl;
}
}
};
int main()
{
MGraph m,M;
m.SetMGraph();
m.prim();
m.kruskal();
}

DS图--最小生成树的更多相关文章

  1. DS图遍历--深度优先搜索

    DS图遍历--深度优先搜索 题目描述 给出一个图的邻接矩阵,对图进行深度优先搜索,从顶点0开始 注意:图n个顶点编号从0到n-1 代码框架如下: 输入 第一行输入t,表示有t个测试实例 第二行输入n, ...

  2. 图-最小生成树算法之Kruskal及其Java实现

    1.Kruskal算法 Kruskal算法基于贪心,因此它追求的是近似最优解,也就是说由Kruskal得出的生成树并不一定是最优解. Kruskal算法求最小生成树的关键在于,每次选取图中权值最小(及 ...

  3. ACM程序设计选修课——Problem E:(ds:图)公路村村通(Prim)

    问题 E: (ds:图)公路村村通 时间限制: 1 Sec  内存限制: 128 MB 提交: 9  解决: 5 题目描述 现有村落间道路的统计数据表中,列出了有可能建设成标准公路的若干条道路的成本, ...

  4. ACM程序设计选修课——Problem F:(ds:图)旅游规划(优先队列+SPFA)

    问题 F: (ds:图)旅游规划 时间限制: 1 Sec  内存限制: 128 MB 提交: 14  解决: 4 题目描述 有了一张自驾旅游路线图,你会知道城市间的高速公路长度.以及该公路要收取的过路 ...

  5. 数据结构学习笔记05图(最小生成树 Prim Kruskal)

    最小生成树Minimum Spanning Tree 一个有 n 个结点的连通图的生成树是原图的极小连通子图,且包含原图中的所有 n 个结点,并且有保持图连通的最少的边. 树: 无回路   |V|个顶 ...

  6. poj 3026 Borg Maze bfs建图+最小生成树

    题目说从S开始,在S或者A的地方可以分裂前进. 想一想后发现就是求一颗最小生成树. 首先bfs预处理得到每两点之间的距离,我的程序用map做了一个映射,将每个点的坐标映射到1-n上,这样建图比较方便. ...

  7. BZOJ 4242 水壶(BFS建图+最小生成树+树上倍增)

    题意 JOI君所居住的IOI市以一年四季都十分炎热著称. IOI市是一个被分成纵H*横W块区域的长方形,每个区域都是建筑物.原野.墙壁之一.建筑物的区域有P个,编号为1...P. JOI君只能进入建筑 ...

  8. 算法学习记录-图——最小生成树之Kruskal算法

    之前的Prim算法是基于顶点查找的算法,而Kruskal则是从边入手. 通俗的讲:就是希望通过 边的权值大小 来寻找最小生成树.(所有的边称为边集合,最小生成树形成的过程中的顶点集合称为W) 选取边集 ...

  9. 算法学习记录-图——最小生成树之prim算法

    一个连通图的生成树是一个极小的连通子图,它包含图中全部的顶点(n个顶点),但只有n-1条边. 最小生成树:构造连通网的最小代价(最小权值)生成树. prim算法在严蔚敏树上有解释,但是都是数学语言,很 ...

随机推荐

  1. github如何删除新建仓库(致新手)

    github作为开发人员的必备用具.那么,作为一个新手如何删除github中建立的仓库呢? 1.以删除My test为例

  2. Linux如何在(localhost)本地打开html

    自己实验的结果,可能不是最好的办法,方法不唯一 1. 下载Tomcat https://www.cnblogs.com/liangweiping/p/5113857.html 如何查看本机的端口服务 ...

  3. websocket介绍 以及 vue websocket使用案例

    1 介绍: https://www.zhihu.com/question/20215561 2 案例: https://www.jianshu.com/p/0d20a032d0ec (坑说明). ht ...

  4. 各种浏览器兼容trim()的方法

    一.利用while方法解决 function trim(str) { while (str[0] == ' ') { str = str.slice(1); } while (str[str.leng ...

  5. redis和memcache的区别(总结)

    1.Redis和Memcache都是将数据存放在内存中,都是内存数据库.不过memcache还可用于缓存其他东西,例如图片.视频等等: 2.Redis不仅仅支持简单的k/v类型的数据,同时还提供lis ...

  6. Python 3.5 in win10 pip install Orange3

    http://www.lfd.uci.edu/%7Egohlke/pythonlibs/ 下载Orange3 以及 依赖包 注意网页上标出的Orange 的依赖,以及 https://github.c ...

  7. Go Example--限速

    package main import ( "fmt" "time" ) func main() { requests := make(chan int, 5) ...

  8. JS中map和foreach的区别以及some和every的用法

    一.原生JS forEach()和map()遍历 共同点: 1.都是循环遍历数组中的每一项. 2.forEach() 和 map() 里面每一次执行匿名函数都支持3个参数:数组中的当前项item,当前 ...

  9. python使用dns轮循检测web服务器是否异常

    我使用的是python2.7,我本来另装了一个python3.6,发现无法安装dnspython,于是只能换回来了 import dns.resolver #这个需要另外下载并安装(下载地址www.d ...

  10. linux系统调用的三种方法

    通过glibc提供的库函数 [23:02:14] gcc chmodtest.c [23:02:17] ls -l kali //记得先创建这个文件 -rwxrwxrwx. 1 root root 0 ...