破圈法求解最小生成树c语言实现(已验证)
破圈法求解最小生成树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语言实现(已验证)的更多相关文章
- CF F. MST Unification (最小生成树避圈法)
题意 给一个无向加权联通图,没有重边和环.在这个图中可能存在多个最小生成树(MST),你可以进行以下操作:选择某条边使其权值加一,使得MST权值不变且唯一.求最少的操作次数. 分系:首先我们先要知道为 ...
- Eratosthenes筛选法求解质数
问题说明: 除了自身之外,无法被其它整数整除的数称之为质数,要求质数很简单,但如何快速的求出质数则一直是程式设计人员与数学家努力的课题, 在这边介绍一个着名的 Eratosthenes求质数方法. 解 ...
- uva11549 Floyd判圈法
题意: 给两个数n, k,每次将k平方取k的前n位,问所有出现过的数的最大值 原来这就是floyd判圈法.. #include<cstdio> #include<cstdlib> ...
- POJ 2135.Farm Tour 消负圈法最小费用最大流
Evacuation Plan Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 4914 Accepted: 1284 ...
- UOJ 117 欧拉回路(套圈法+欧拉回路路径输出+骚操作)
题目链接:http://uoj.ac/problem/117 题目大意: 解题思路:先判断度数: 若G为有向图,欧拉回路的点的出度等于入度. 若G为无向图,欧拉回路的点的度数位偶数. 然后判断连通性, ...
- POJ 1061 青蛙的约会(拓展欧几里得算法求解模线性方程组详解)
题目链接: BZOJ: https://www.lydsy.com/JudgeOnline/problem.php?id=1477 POJ: https://cn.vjudge.net/problem ...
- Coursera在线学习---第一节.梯度下降法与正规方程法求解模型参数比较
一.梯度下降法 优点:即使特征变量的维度n很大,该方法依然很有效 缺点:1)需要选择学习速率α 2)需要多次迭代 二.正规方程法(Normal Equation) 该方法可以一次性求解参数Θ 优点:1 ...
- 基本算法思想之递推算法思想(C++语言描述)
递推算法是非常常用的算法思想,在数学计算等场合有着广泛的应用.递推算法适合有明显公式规律的场合. 递推算法基本思想 递推算法是一种理性思维莫斯的代表,根据已有的数据和关系,逐步推到而得到结果.递推算法 ...
- 逆波兰法求解数学表达示(C++)
主要是栈的应用,里面有两个函数deleteSpace(),stringToDouble()在我还有一篇博客其中:对string的一些扩展函数. 本程序仅仅是主要的功能实现,没有差错控制. #inclu ...
随机推荐
- Windows中使用ssh利用公钥登入远程服务器
方式:使用 Winscp 密钥登录 我们平时开发多会使用 ftp 来上传下载文件,尤其是很多 Linux 环境下. 其实 Linux 默认是不提供 ftp 的,需要你额外安装 FTP 服务 ...
- 秒杀linux下系统调用fork()面试题(转)
https://blog.csdn.net/chdhust/article/details/10579001 https://www.cnblogs.com/clover-toeic/p/375443 ...
- Python学习小纪
1.打包发布*.py文件---"文件路径下打开命令行 d:\python\python.exe setup.py sdist" eg:打包发布f:\C\python\print_l ...
- 20175320 2018-2019-2 《Java程序设计》第6周学习总结
20175320 2018-2019-2 <Java程序设计>第6周学习总结 教材学习内容总结 本周学习了教材的第七及第十章的内容.在这两章中介绍了接内部类与异常类以及输入.输出流,第七章 ...
- django的闪现和增、删、改、查
使用 messages 闪现在views.py中导入 from django.contrib import messages 在html中 {% if messages %} {% for mess ...
- 平安银行在开源技术选型上的思考和实践 RocketMQ
小结: 1. https://mp.weixin.qq.com/s/z_c5D8fvHaYvHSczm0nYFA 平安银行在开源技术选型上的思考和实践 平安银行·吴建峰 阿里巴巴中间件 3月7日 随着 ...
- redis加固
一.背景描述 1.漏洞描述 Redis 因配置不当存在未授权访问漏洞,可以被攻击者恶意利用. 在特定条件下,如果 Redis 以 root 身份运行,黑客可以给 root 账号写入 SSH 公钥文件, ...
- js把页面的table标签导出为csv
// 使用该保存方法,table必须外嵌一个div且不能有任何其他元素 否则ie下载会出现其他数据 //tableid , title 为文件保存的文件名 function saveCode(tabl ...
- JVM深入:JVM内存堆布局图解分析(转)
转载自:https://www.cnblogs.com/SaraMoring/p/5713732.html 原文:http://www.codeceo.com/article/jvm-memory-s ...
- python tkinter entry
"""小白随笔,大佬勿喷""" '''Entry编辑框 收集数据''' import tkinter as tk import tkinte ...