您的位置:首页 > 其它

最小生成树的胡思乱想--做减法

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]--;

}

//这里其实应该已经得出最后的最小生成树了

//由于是刚冒出的想法,可能还有地方存在漏洞,需要验证。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: