破圈法求解最小生成树c语言实现(已验证)

下面是算法伪代码,每一个算法都取一个图作为输入,并返回一个边集T。

对该算法,证明T是一棵最小生成树,或者证明T不是一棵最小生成树。此外,对于每个算法,无论它是否能计算出一棵最小生成树,都要给出其最有效的实现。

MAYBE-MST-A(G,w)

Sort the edges into nonincreasing order of edge weights w

T<-E

For each edge e, taken in nonincreasing order by weight

Do if T-{e} is a connected graph

    Then T<-T-e

Return T

算法基本思想:

先将图G的边按照权的递减顺序排列后,依次检验每条边,在保持连通的情况下,每次删除最大权边,直到所有边都被遍历到无法删除任何一边(或余下n-1条边为止)。

证明:

生成树证明:

1、     如果给定连通图G没有回路,那么G本身就是一棵生成树

2、     如果G中只有一个回路,则删去G的回路上的一条边(不删除节点),则产生的图仍是连通的且没有回路,则得到的子图就是G的一棵生成树;

3、     如果G的回路不止一个,只要删去每一个回路上的一条边,知道G的子图是连通且没有回路且与图G有一样的结点集,那么这个子图就是一棵生成树。

4、     重复步骤3,则直到所有边都不能删除,由于删除判断条件,得到的子图就是一棵生成树。

MST证明:

若在某个回路C中有一条唯一的最长边,则T­­­*中一定不含这条边,因为优先删除回路中最长的边。

若在某个边e的割集中有一条唯一一条最短边,则T*中一定含有这条边(The Cut Property:考虑图G中的一条边e。如果存在一个cut(A,B),使得e是所有跨越该割的所有边中权重最小者,则e一定在G的MST中。

),且不含有其他边,因为一旦含有其他边就构成了回路(Lonely-Cut Corollary如果边e是跨越了cut(A, B)的唯一一条边,则e不可能在任一圈中。)。

反向证明:假设T*中跨越cut(A,B)的边不只一条,则在算法结束之前一定会遍历到其中的成圈的边(Double-Crossing),根据权值选取方法和删除圈的一边仍为连通图的条件,一定会将权值较大的边删除,直到无环且剩下的唯一一条边是最短边。

算法变量:

a[n][n]:带权图的邻接矩阵,a[i][j]=w或a[i][j]=0;

max:标记当前找到的准备删去的边的权值;

p:标记找到的要删去的权值所在的行号;

q:标记找到的要删去的权值所在的列好;

am:标记找到的最大元素(am是为了保护权值大但不能删的边),如果a[i][j]不能删除,则可以让a[p][q]=am,a[q][p]=am来还原刚才删去的边;

I,j:二维数组的行号和列号

sm:图的边数,每删除一个边,sm就减1,当sm=n-1时,结束

wt:最小生成树的权值和

算法实现(c语言)

 #include<stdio.h>
BY Yuanshuai Zheng,UESTC
#define n 5
int a[n][n];
int flag,am,p,q;
INPUT()
{
int i,j;
printf("输入图的带权邻接矩阵:\n");
for(i = ;i<n;i++)
{
for(j=;j<n;j++)
scanf("%d",&a[i][j]);
}
}
OUTPUT(int a[n][n])
{
int i,j;
for(i=;i<n;i++)
{
for(j=;j<n;j++)
printf("%5d",a[i][j]);
printf("\n");
}
}
MAX(int a1[n][n],int am1,int p1,int q1)
{
int i,j,ptm,qtm;
int max;
max = ;
for(i=;i<n;i++)
{
for(j=i;j<n;j++)
if((a1[i][j]>max)&&(a1[i][j]<=am1)&&((i!=p1)||(j!=q1)))
{
max = a1[i][j];
ptm = i;
qtm = j; }
}
am = max;
printf("max=%5d\t",am);
p = ptm;
q = qtm;
a[p][q]=;
a[q][p]=;
}
WSHALL(int array[n][n])
{
int i,j,k,m=;
int r[n][n],B[n][n];
for(i=;i<n;i++)
{
for(j=;j<n;j++)
{
r[i][j]=;
B[i][j]=array[i][j];
//分界线
if(array[i][j]>=)
B[i][j]=;
else
B[i][j]=;
//分界线
}
}
for(j=;j<n;j++)
{
for(i=;i<n;i++)
if(B[i][j]>=)
{
for(k=;k<n;k++)
{
if(B[k][i]>=)
{
B[k][j]=B[j][k]=;
}
}
}
}
for(i=;i<n;i++)
{
for(j=;j<n;j++)
if(!B[i][j])
{
return ;
}
}
return ;
} //方法1
// for(k=0;k<n;k++)
// B[i][j]=B[i][k]+B[j][k];
// }
// }
// for(i=0;i<n;i++)
// {
// for(j=0;j<n;j++)
// {
// r[i][j]=B[i][j];
// {
// if((r[i][j]>=1)||(i==j))
// m=m+1;
// }
// }
// }
// printf("m=%d\t",m);
// if(m==n*n)
// flag = 1;
// else
// flag=0;
// return(flag); int main()
{
int i,j,sm,wt=;
am = ,p=-,q=-,sm=;
INPUT();
for(i=;i<n;i++)
{
for(j=i;j<n;j++)
{
if(a[i][j]>)
sm = sm+;
}
}
printf("\nsm=%d\n",sm);
printf("输出图的带权邻接矩阵:\n");
OUTPUT(a);
printf("\n");
while(sm>n-)
{
MAX(a,am,p,q);
flag=WSHALL(a);//华沙尔算法判断是否连通
//printf("flag= %d",flag);
{
if(flag==)
{
sm=sm-;
//printf("flag= %d",flag);
}
else
{
a[p][q]=am;
a[q][p]=am;
}
}
}
for(i=;i<n;i++)
for(j=i;j<n;j++)
{
wt=wt+a[i][j];
}
printf("\n\n输出最小生成树的带权邻接矩阵:\n");
OUTPUT(a);
printf("最小生成树的树权是: %d\n",wt);
}

代码验证:

例子:

0

6

10

0

0

6

0

3

8

5

10

3

0

6

7

0

8

6

0

0

0

5

7

0

0

破圈法求解最小生成树c语言实现(已验证)的更多相关文章

  1. CF F. MST Unification (最小生成树避圈法)

    题意 给一个无向加权联通图,没有重边和环.在这个图中可能存在多个最小生成树(MST),你可以进行以下操作:选择某条边使其权值加一,使得MST权值不变且唯一.求最少的操作次数. 分系:首先我们先要知道为 ...

  2. Eratosthenes筛选法求解质数

    问题说明: 除了自身之外,无法被其它整数整除的数称之为质数,要求质数很简单,但如何快速的求出质数则一直是程式设计人员与数学家努力的课题, 在这边介绍一个着名的 Eratosthenes求质数方法. 解 ...

  3. uva11549 Floyd判圈法

    题意: 给两个数n, k,每次将k平方取k的前n位,问所有出现过的数的最大值 原来这就是floyd判圈法.. #include<cstdio> #include<cstdlib> ...

  4. POJ 2135.Farm Tour 消负圈法最小费用最大流

    Evacuation Plan Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 4914   Accepted: 1284   ...

  5. UOJ 117 欧拉回路(套圈法+欧拉回路路径输出+骚操作)

    题目链接:http://uoj.ac/problem/117 题目大意: 解题思路:先判断度数: 若G为有向图,欧拉回路的点的出度等于入度. 若G为无向图,欧拉回路的点的度数位偶数. 然后判断连通性, ...

  6. POJ 1061 青蛙的约会(拓展欧几里得算法求解模线性方程组详解)

    题目链接: BZOJ: https://www.lydsy.com/JudgeOnline/problem.php?id=1477 POJ: https://cn.vjudge.net/problem ...

  7. Coursera在线学习---第一节.梯度下降法与正规方程法求解模型参数比较

    一.梯度下降法 优点:即使特征变量的维度n很大,该方法依然很有效 缺点:1)需要选择学习速率α 2)需要多次迭代 二.正规方程法(Normal Equation) 该方法可以一次性求解参数Θ 优点:1 ...

  8. 基本算法思想之递推算法思想(C++语言描述)

    递推算法是非常常用的算法思想,在数学计算等场合有着广泛的应用.递推算法适合有明显公式规律的场合. 递推算法基本思想 递推算法是一种理性思维莫斯的代表,根据已有的数据和关系,逐步推到而得到结果.递推算法 ...

  9. 逆波兰法求解数学表达示(C++)

    主要是栈的应用,里面有两个函数deleteSpace(),stringToDouble()在我还有一篇博客其中:对string的一些扩展函数. 本程序仅仅是主要的功能实现,没有差错控制. #inclu ...

随机推荐

  1. vue菜鸟从业记:公司项目里如何进行前后端接口联调

    最近我的朋友王小闰进入一家新的公司,正好公司项目采用的是前后端分离架构,技术栈是王小闰非常熟悉的vue全家桶,后端用的是Java语言. 在前后端开发人员碰面之后,协商确定好了前端需要的数据接口(扯那么 ...

  2. 记录C#中的扩展方法

    C#中的扩展方法. 系统自带的类型,我们无法去修改: 修改源代码需要较大的精力,而且可能会带来错误: 我们只是需要一个或者较少的几个方法,修改源代码费时费力: 被扩展的类是sealed的,不能被继承: ...

  3. 使用MDI 和 XtraTabbedMdiManager 后 选项卡切换后Ribbon 合并后不选中MDI子窗...

    使用MDI 和 XtraTabbedMdiManager 后 选项卡切换后Ribbon 合并后不选中MDI子我这里是 继承 XtraTabbedMdiManager  所以,是重载的  OnSelec ...

  4. laravel整合vue 多入口解决

    2018年8月10日23:10:29 其实整合是挺简单,因为laravel本身就准备的挺好了 laravel 版本5.6   注意php cli是web是不一样的 这个需要设置环境变量 ,php需要7 ...

  5. Akka并发编程框架 -概念模型(Akka.net或者Orleans)

    Akka 来构建具备高容错性.可以横向扩展的分布式网络应用程序. Akka 通常是指一个强大的分布式工具集,用于协调远程计算资源来进行一些工作 Akka 工具集以及Actor 模型的介绍. Actor ...

  6. 保护模式.vbs

    Sub Main Dim cnt Dim delay delay = 10000 For cnt = 0 To 80 crt.screen.Send "interface optical-r ...

  7. -ms、-moz、-webkit -o

    -ms-transform:rotate(7deg); //-ms代表ie内核 识别码-moz-transform:rotate(7deg); //-moz代表火狐内核识别码 -webkit-tran ...

  8. mysql-8.0.15-winx64 解压版安装

    官网下载了一个 mysql-8.0.15-winx64.zip 版本,解压部署过程记录如下: 1.将zip包解压到D盘 2.配置环境变量 在Path中加入D:\Program Files\mysql- ...

  9. python生成excel测试数据

    在功能测试时,经常会测到excel文件导入导出的功能,导入与导出时,需要测试系统单次导入大批量数据时是否正常, 如果系统承受不起太大的数据导入,则需要开发限制单次导入的数量,以防止系统服务异常.大量的 ...

  10. CAS单点登录入门

    一.单点登录简介 SOO是现在企业比较流行的业务整合解决方案之一,定义解决登录,可以应用在不同系统中,用户只需要登录一次,就可以访问所有相互信任的应用系统(模块开发.同家公司不同产品等等),例如百度, ...