对于一个边上具有权值的图来说,其边权值和最小的生成树叫做图G的最小生成树

求无向图最小生成树主要有prim和kruskal两种算法

1.prim

将点集V分成Va和Vb两部分,Va为已经连入生成树的点,Vb为没有连入的点,按照边的大小逐渐向Va中加点,直到Va中包含所有点,具体步骤,复杂度O(mlogn)

⑴.首先初始化生成树的权值为0,任选一点放入Va,其余点放入Vb

⑵.在Vb中找一点u,在Va中找一点v(其实v一直不变),使得uv间距离最短,并更新u所连边,这也就是为什么v不变的原因

⑶.重复步骤2,直到Vb中没有点为止

#include <queue>
#include <vector>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <algorithm>
const double INF=0x3f3f3f3f;
using namespace std;
double dis[],G[][];
int n,x[],y[],vis[];
double prim(int v){
int i,j,u;
double sum,tmp;
sum=;
memset(vis,,sizeof(vis));
for(i=;i<=n;i++)
dis[i]=G[v][i];
vis[v]=;
for(i=;i<n;i++){
u=v;
tmp=INF;
for(j=;j<=n;j++)
if(dis[j]<tmp&&vis[j]==){
tmp=dis[j];
u=j;
} //找出与v相连最小的边
sum+=tmp;
vis[u]=;
for(j=;j<=n;j++)
if(!vis[j]){
if(dis[j]>G[u][j])
dis[j]=G[u][j];
} //更新与u相连的边的权值
}
return sum;
}
int main(){
int i,j;
double ans;
scanf("%d",&n);
for(i=;i<=n;i++)
scanf("%d%d",&x[i],&y[i]);
for(i=;i<=n;i++)
for(j=;j<=n;j++)
G[i][j]=sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]));
ans=prim(); //通过每个点的坐标算出每个点间距离
printf("%.2lf\n",ans);
return ;
}

2.kruskal

基于贪心的思想逐渐加入边并判断是否形成环,复杂度O(mlogm)

⑴.初始化,并将E进行排序

⑵.不断将边加入图中,并判断是否形成环

⑶.判断选择的边是否是n-1,并计算步骤2的权值和

#include <queue>
#include <vector>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
int V,E;
int par[],ran[],vis[];
void init(int n){
int i;
for(i=;i<=n;i++){
ran[i]=;
par[i]=i;
}
}
int find(int x){
if(par[x]==x)
return x;
return par[x]=find(par[x]);
}
void unite(int x,int y){
x=find(x);
y=find(y);
if(x==y)
return;
if(ran[x]<ran[y])
par[x]=y;
else{
par[y]=x;
if(ran[x]==ran[y])
ran[x]++;
}
}
bool same(int x,int y){
return find(x)==find(y);
} //并查集判断是否有环
struct node{
int u,v,cost;
};
bool cmp(node a,node b){
return a.cost<b.cost;
}
node es[];
int kruskal(){
int i;
int res=;
init(V);
sort(es,es+E,cmp);
for(i=;i<E;i++){
node e=es[i];
if(!same(e.u,e.v)){
unite(e.u,e.v);
res+=e.cost;
}
}
return res;
}
int main(){
int i;
scanf("%d%d",&V,&E);
memset(vis,,sizeof(vis));
for(i=;i<E;i++)
scanf("%d%d%d",&es[i].u,&es[i].v,&es[i].cost);
printf("%d\n",kruskal());
return ;
}

3.次小生成树

基于最小生成树的算法演变出次小生成树,其实基本的思想就是连入一条不在最小生成树上的边,从而形成一个环,去掉在环中并且在最小生成树上最大的边,遍历所有不在最小生成树上的边并进行同样的操作最小值即为次小生成树,简单证明就是连入一条边后去掉一个最大值相当于比原来的值增加的值最小(增加量=添加的边-环上的某一条边(并且这条边在最小生成树上),添加的边的权值一定,因此使环上的边最大),因次去掉最大的边,kruskal的复杂度是O(mlogm),求出环上的最大值复杂度是O(n*n),因此次小生成树的复杂度是O(mlogm+n*n)

#include <math.h>
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
const double INF=0x3f3f3f3f;
using namespace std;
int dis[],path[][],G[][];
int n,m,pre[],vis[],used[][];
int prim(int v){
int i,j,u,sum,tmp;
sum=;
memset(vis,,sizeof(vis));
memset(used,,sizeof(used));
memset(path,,sizeof(path));
for(i=;i<=n;i++){
dis[i]=G[v][i];
pre[i]=;
}
vis[v]=;
for(i=;i<n;i++){
u=v;
tmp=INF;
for(j=;j<=n;j++)
if(dis[j]<tmp&&vis[j]==){
tmp=dis[j];
u=j;
}
sum+=tmp;
vis[u]=;
used[u][pre[u]]=used[pre[u]][u]=;
for(j=;j<=n;j++){
if(vis[j]&&j!=u) //从j到父节点上的边的最大值和最小生成树上的边之间求最大值
path[u][j]=path[j][u]=max(path[j][pre[u]],dis[u]);
if(!vis[j]){ //与dp有些类似
if(dis[j]>G[u][j]){
dis[j]=G[u][j];
pre[j]=u;
}
}
}
}
return sum;
}
int second_prim(int tmp){
int i,j,ans;
ans=INF;
for(i=;i<=n;i++)
for(j=;j<=n;j++){
if(i!=j&&used[i][j]==)
ans=min(ans,tmp+G[i][j]-path[i][j]);
} //遍历每条边求次小生成树
return ans;
}
int main(){
int i,j,x,y,z,ans,tmp;
scanf("%d%d",&n,&m);
memset(G,INF,sizeof(G));
for(i=;i<=m;i++){
scanf("%d%d%d",&x,&y,&z);
G[x][y]=G[y][x]=z;
}
tmp=prim(); //先求出最小生成树
ans=second_prim(tmp);
printf("%d\n",ans);
return ;
}

BY  http://blog.csdn.net/stay_accept/article/details/50960185

最小生成树&&次小生成树的更多相关文章

  1. 训练指南 UVALive - 5713(最小生成树 + 次小生成树)

    layout: post title: 训练指南 UVALive - 5713(最小生成树 + 次小生成树) author: "luowentaoaa" catalog: true ...

  2. [ An Ac a Day ^_^ ] [kuangbin带你飞]专题八 生成树 UVA 10600 ACM Contest and Blackout 最小生成树+次小生成树

    题意就是求最小生成树和次小生成树 #include<cstdio> #include<iostream> #include<algorithm> #include& ...

  3. URAL 1416 Confidential (最小生成树+次小生成树)

    Description Zaphod Beeblebrox - President of the Imperial Galactic Government. And by chance he is a ...

  4. POJ 1679 The Unique MST 【最小生成树/次小生成树模板】

    The Unique MST Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 22668   Accepted: 8038 D ...

  5. 最小生成树(次小生成树)(最小生成树不唯一) 模板:Kruskal算法和 Prim算法

    Kruskal模板:按照边权排序,开始从最小边生成树 #include<algorithm> #include<stdio.h> #include<string.h> ...

  6. HDU 4081 Qin Shi Huang&#39;s National Road System(最小生成树/次小生成树)

    题目链接:传送门 题意: 有n坐城市,知道每坐城市的坐标和人口.如今要在全部城市之间修路,保证每一个城市都能相连,而且保证A/B 最大.全部路径的花费和最小,A是某条路i两端城市人口的和,B表示除路i ...

  7. (最小生成树 次小生成树)The Unique MST -- POJ -- 1679

    链接: http://poj.org/problem?id=1679 http://acm.hust.edu.cn/vjudge/contest/view.action?cid=82831#probl ...

  8. POJ 1679 The Unique MST (次小生成树)

    题目链接:http://poj.org/problem?id=1679 有t组数据,给你n个点,m条边,求是否存在相同权值的最小生成树(次小生成树的权值大小等于最小生成树). 先求出最小生成树的大小, ...

  9. URAL 1416 Confidential --最小生成树与次小生成树

    题意:求一幅无向图的最小生成树与最小生成树,不存在输出-1 解法:用Kruskal求最小生成树,标记用过的边.求次小生成树时,依次枚举用过的边,将其去除后再求最小生成树,得出所有情况下的最小的生成树就 ...

随机推荐

  1. 一个无法解析的外部命令and无法解析的外部符号

    出现错误: 解决: 因为修改了函数定义的参数,但是没有修改函数声明的参数 把参数统一一下就行了

  2. 部署java应用的几种方式

    J2EE应用 该应用根目录下有好多文件夹和以jsp结尾的文件 部署时,需要在tomcat的conf目录下的server.xml文件中添加上<Context path="/" ...

  3. Laravel with 查询指定的字段(非复制的哦)

    问题: 在with里面指定查询字段,结果是null. 在模型里面指定查询字段,结果是null. 解决办法: 在查询指定字段的时候要顺带着查询关联的外键,例: // user 表 id name // ...

  4. 关于微信小程序获取多个formId的实现方法

    在此之前,很多人使用过form和button的多层嵌套来实现点击一次获取多个formId的目的,如下图所示,点击一次“提交”,可以获取到多个formId 但是在今年3月份,这个投机取巧的方法(算是微信 ...

  5. golang包管理工具

    软件开发中,不可避免的会使用到第三方库,因此包管理工具可以极大的方便开发者管理第三方依赖,避免掉入"依赖地狱". 作为google强大背书的golang语言,golang官方包管理 ...

  6. css垂直居中如何实现

    利用CSS3的transform:translate .center{ width:%; position: absolute; top: %; left: %; -moz-transform: tr ...

  7. Python之定义默认参数

    定义函数的时候,还可以有默认参数. 例如Python自带的 int() 函数,其实就有两个参数,我们既可以传一个参数,又可以传两个参数: >>> int('123') 123 > ...

  8. dubbo线程池作用于接口而不是方法

    记一次线上dubbo服务超时和线程池满问题排查 可能调用的接口没问题,但是该服务中的其他接口占用完了线程池,导致调用超时被拒绝处理.

  9. Oracle nvl()函数处理null值

    首先我先说一下什么是Oracle的函数,曾经有一位大牛,让我说说熟悉的oracle函数,我当时竟一头雾水,心想“什么oracle函数啊,不就是那些SQL语句吗“,当时我竟然说出了select之类的回答 ...

  10. 【OGG 故障处理】 丢失归档恢复

    OGG 有两天由于某种原因没有启动,而这段时间的备份文件缺失了一部分归档.恢复过程记录如下: GGSCI (xxxx) > info all Program Status Group Lag a ...