最小生成树的胡思乱想--做减法
2017-11-19 17:33
169 查看
最小生成树的胡思乱想–做减法
今天看到最小生成树的算法忽然想到 为什么现在的做法都是在 做加法呢?
为什么不尝试一下减法呢?
比如说我们的顶点数n,边数m n和m相差不多。
如果我们做加法的话要做 n-1条,假如说n比较大
但是我们如果**做减法,
应该只需要 ( m-(n-1) )条**,
因为前提已经有 (m-n)是一个很小的可以接受的数了,
所以我们可以得出 做减法 需要减去的条数
是会远远小于 做加法 需要加起来的条数的
两者的目的最终都是为了生成最小生成树
就当是我瞎想了,看看能不能证明。
好吧,下面就先记录一下自己不太成熟的算法:
开始需要明确一点,就是最小生成树是针对无向图来说的。
首先,
n为顶点数,m为边数
定义一个G[MAXV][MAXV],将每条边的边权存放进来。
其中,MAXV是最大顶点数。例如:const int MAXV=510;
定义一个int inq[MAXV]={0},标记数组,初始值为0,标记图中的 各个顶点
分别被集合s中si条边包含,则对应的inq[i] = si;
判断是否满足生成树,也就是加入集合s中的边是否将所有的点都包含了进来。
什么时候生成树一定不满足呢?
就是inq数组中1~n 或者是0~n-1编号的n个
顶点有任意一个 inq[i]=0;
这种情况就一定不满足了。
先说一种粗略的,以后再想能不能剪枝。
首先接收外部数据u,v,w。分别是每条边的两个顶点及边权
因为是无向图,而且其实,这个算法考虑了 u->v 了,就
不用重复考虑 v->u 这个地方可以省一点空间和时间。
//定义无穷大 const int INF=0x3fffffff; scanf("%d%d",&n,&m); //**此处是以编号0~n-1 为例** //**初始时默认不可达** fill(G[0],G[0]+MAXV*MAXV,INF); for(int i=0;i<m;i++) { scanf("%d%d%d",&u,&v,&w); G[u][v]=w; //如果上面的节省步骤实现,就不用保留其中一个了 inq[u]+=1; //如果上面的节省步骤实现,这里也会修改 inq[v]+=1; //而且要记得是累加!!! } //以上工作全是属于初始化工作 //以下是算法阶段
首先我想说一下特殊情况,就是
初始化工作完成之后,inq[]数组中 0~n-1 仍然有 0 值元素
也就是本身提供的图G不足以达到生成最小生成树的条件,此时
也就根本没有必要 去 生成最小生成树,直接退出。
//其实我一直在想是不是还有什么更好的容器来替代inq数组 //set? map? priority_queue? queue? stack? vector? bool is_tree=true; for(int i=0;i<n;i++) { if(inq[i]==0) { is_tree=false; break; } } if(!is_tree) { printf("无法生成最小生成树!!"); return; } //以上其实还可以加一个判断,以上的处理其实是针对m>n的时候的处理 //还可以加下面的判断,有点多此一举,但是下面的判断在某些情况下 //省下了遍历的阶段,可以直接退出。 /* if(m<n-1 ) { printf("无法生成最小生成树!!"); return; } */ //如果可以生成最小生成树,则继续下面的算法 int now_edge=m; //做减法,要求就是谁大减谁,哪条边大减谁 //但是这里也是可以剪枝的,就是如果减去这条边的话, //对应的与其相连的点会出现 inq[u]==0 || inq[v] == 0 的情况, //也就是没剪之前 出现 inq[u]==1 || inq[v] == 1 这样的话 //这条边就不可以减 ,继续寻找下一个较大的边。。。直到找到。或者now_edge==n-1时为止 //自动排序的话,或许之后可以考虑用到优先队列priority_queue while(now_edge!=n-1) { //以下就是筛选最大元素的过程,或许还能进化 int u=-1,v=-1,MAX=-1; for(int i=0;i<n;i++) { for(int j=i+1;j<n;j++) { if( inq[i]>1 && inq[j]>1 && MAX< G[i][j] ) { u=i; v=j; MAX=G[i][j]; } } } G[u][v]=INF; now_edge--; inq[u]--; inq[v]--; } //这里其实应该已经得出最后的最小生成树了 //由于是刚冒出的想法,可能还有地方存在漏洞,需要验证。
相关文章推荐
- CCF 201703-4 地铁修建(最小生成树 + 并查集)
- Kruskal算法(求最小生成树)
- 最小生成树
- HDU 1162 Eddy's picture (最小生成树)
- 文章标题 POJ 1789 :Truck History (最小生成树+prim)
- 2011-02-26 CLRS Chapter23 Minimum Spanning Trees 最小生成树
- 数据结构:最小生成树--Prim算法
- [JSOI2008]最小生成树计数
- 【各大OJ】最小生成树专题
- 【最小生成树】【kruscal】hdu4786 Fibonacci Tree
- POJ-1287-Networking [最小生成树]
- 最小生成树--克鲁斯卡尔算法
- HDU 1863 畅通工程(prime——最小生成树)
- 最小生成树Prim算法理解
- BZOJ 2561(最小生成树-最小割)
- POJ2031 最小生成树
- POJ 2031:Building a Space Station 最小生成树
- 最小生成树_AOV网(拓扑排序)_AOE网(关键路径)_最短路径
- 【贪心法求解最小生成树之Kruskal算法详细分析】---Greedy Algorithm for MST
- 最小生成树(kruskal算法)