集训8.16最小生成树讲解
来源:互联网 发布:长篇小说投稿 知乎 编辑:程序博客网 时间:2024/06/05 04:28
最小生成树(mst),无向图,什么是最小生成树,最小生成树就是包括所有顶点(不一定成环)且权值之和最小,涉及到这类题目,有时候题目保证一定有最小生成树,没有题目会说没有输出-1等等,怎么判断有没有下面讲解过程中提到,与最小生成树相反的是最大生成树,有时候题目保证一定有最大生成树,没有题目会说没有输出-1等等,怎么判断有没有下面讲解过程中提到。
最小生成树的算法有两个一个是prim算法另一个是kruskal算法
prim算法
算法描述:任意选出一个顶点作为初始顶点(我都是选第一个顶点),v是顶点的集合,一开始为空,以后陆续将顶点加入集合,全部顶点加入集合就得到最小生成树,
任选一个顶点放入树,初始化v和lowcost
在那些一个顶点在树里另一个端点不在树里的边中选一个边权最小的边,将此边和端点加入数,执行更新,重复上一步知道所有顶点都入树
实现代码:
void prim()
{
memset(v,0,sizeof(v));
v[1]=1;
for(i=1;i<=n;i++)n节点个数
lowcost[i]=edge[1][I];
for(i=2;i<=n;i++)n节点个数
{
min=inf;(最大生成树时min=-inf)
for(j=1;j<=n;j++)
{
if(!v[j]&&minn>lowcost[j])(求最大生成树时if(!v[j]&&minn<lowcost[j]){minn=lowcost[j];next=j;}
{
minn=lowcost[j];
next=j;
}
}
(
判断是否能构成最小生成树
if(minn==inf)
{cout<<-1<<endl;return ;}
判断是否能构成最大生成树
if(minn==-inf)
{cout<<-1<<endl; return ;}
)
sum+=minn;
v[next]=1;
for(j=1;j<=n;j++)
{
if(!v[j]&&lowcost[j]>edge[next][j])(求最大生成树时if(!v[j]&&lowcost[j]<edge[next][j]) lowcost[j]=edge[next][j];)
lowcost[j]=edge[next][j];
}
}
cout<<sum<<endl;
}
int main()
{
若题目以矩阵的形式给出
for(i=1;i<=n;i++)
for(j=1;j)<=n;j++) edge[i][j]=
若不是以矩阵的形式给出 需要初始化edge
for(i=1;i<=n;i++)n是节点个数
for(j=1;j<=n;j++) edge[i][j]=inf;(求最大数时赋值为-inf)
初始化完之后输入是 edge[i][j]=edge[j][i]=
若有重边只需在初始化完之后输入时加个判断
if(edge[i][j]>c)选重边中最小的
edge[i][j]=edge[j][i]=c (求最大生成树时若有重边只需在初始化之后输入时加个判断 if(edge[i][j]<c)选重边中最大的 edge[i][j]=edge[j][i]=c)
prim();
}
kruscal算法:
算法描述:
将边权由小到大排序(求最大生成树时只需将边权由大到小排序其余一样)
初始化fat[x]=x;
tot=0;
计数器 k=0;
将边权排序
if(他俩不在一个集合里)
{合并 tot+=w(u,v);k++;}
if(k=顶点个数-1) 树已生成
实现代码:
struct node
{
int s,e,v;//起点终点权值
};
bool cmp(node a,node b)
{
return a.v<b.v;
}
int find(int x)
{
if(fat[x]!=x)
fat[x]=find(fat[x]);
return fat[x];
}
void nuionn(int x,int y)
{
int fa=find(x);
int fb=find(y);
if(fa!=fb) fat[fa]=fb;
}
int main()
{
如果以矩阵的形式给出
m=0;
for(i=1;i<=n;I++)
{
for(j=1;j<=m;j++)
{
cin>>x;
if(x!=0)
{
m++;
edge[m].s=I;
edge[m].e=j;
edge[m].v=x;
}
}
}
如果不以矩阵的形式给出
for(i=1;i<=m;i++)//m边数
{
cin>>a>>b>>c;
edge[I].s=a;edge[I].e=b;edge[I].v=c;
}
for(i=1;i<=n;i++) fat[i]=i;n是顶点的个数
sort(edge+1,edge+1+m,cmp);
tot=0;k=0;
for(i=1;i<=m;I++)m边数
{
if(find(edge[I].s)!=find(edge[I].e)
{
union(edge[I].s,edge[I].e);
tot+=edge[I].v;
k++;
}
}
if(k==n-1) cout<<tot<<endl;
else cout<<-1<<endl;//没生成树
}
- 集训8.16最小生成树讲解
- 最小生成树讲解
- 【最小生成树】讲解
- 最小生成树讲解
- 最小生成树的讲解
- 17寒假集训_贪心与最小生成树
- 2017暑假集训 div1 最小生成树(1)
- sduacm2016级暑假集训 最短路&最小生成树
- 最小生成树 prim算法 讲解
- 2011清华集训.BZOJ2561 && THU A1277.最小生成树(最小割)
- ACM暑期集训——专题一[最小生成树prim算法]
- 暑假集训 8.18 数据结构实验之图论六:村村通公路 (最小生成树)
- poj1679The Unique MST判断最小生成树是否唯一以及求次小生成树边权和的讲解
- 图论总结,查分约束系统讲解,最短路,最小生成树,二分图
- 最小比例 最小生成树
- 最小生成树&&次最小生成树
- 最小生成生成树计数
- 树+最小生成树
- Oracle程序的优点和我缺点我是这样喜欢它的
- Java继承知识点总结(加面试题实例)
- 简单使用JTable读取数据库的表
- Rotate List leetcode java
- java中集合工具类Collections的使用
- 集训8.16最小生成树讲解
- 台湾大学林轩田机器学习技法课程学习笔记15 -- Matrix Factorization
- 用Tensorflow训练的AI玩flappy bird小游戏
- poj 1061 青蛙的约会
- jQuery ajax()请求数据工作笔记
- Java简单实现多线程复制文件
- offset家族
- 【MFC学习】菜单资源
- 个人总结php笔试题五