总结。8月6号图论-关于最小生成树

今天学的内容是图论更深层次的东西:最小生成树。
先总结下概念:
一个无向图中,用且只用(n-1)条边连接n个点得到的一条路径(一棵树),叫做该图的生成树。所以由此概念就可以想到一个图中可能会有多棵生成树。
而当生成树的所有权值和与该图中其他生成树权值和最小时,则该树即为图中最小生成树。(终于解释完了)

好吧粘下官方版:
生成树:一个|V|个点的图,取其中|V|-1条边,并连接所有的顶点,则组成原图的一个生成树
属性:|v|-1条边、连通、无环。
最小生成树:加权图的最小生成树是一棵生成树,其所有边的权值之和不会大于其它任何生成树。
简单讲:找出连接所有点的最低成本路线(我去真简单)

下面是算法方面:

1)普瑞姆算法(MST_prim)
思路:其实和dijkstra算法感觉超像啊。一样分(枚举/未枚举)两个集合,一样是枚举每个点。
– 
1).将1号节点置入集合S中。
2).找到所有连接S中的节点和非S中的节点的边中的权值最小的那一条,并标记这条边,同时将连接的非S中的节点加入S集合。
3).重复2步骤,直到所有节点都在S中。
 

void MST_Prim(int s)
{
 memset(dis,10,sizeof(dis));
 for(int i=1;i<=n;i++)
  dis[i]=a[s][i];
 memset(vis,0,sizeof(vis));
 vis[s]=1;sumn=0;
 for(int i=2;i<=n;i++)
 {
  int minn=a[0][0],c=0;
  for(int j=1;j<=n;j++)
   if((!vis[j])&&(dis[j]<minn))
   {
    minn=dis[j];
    c=j;
   }
  vis[c]=1;
  sumn+=minn;
  for(int j=1;j<=n;j++)
   if((a[c][j]<dis[j])&&(!vis[j]))
    dis[j]=a[c][j];
 }
}



2)克鲁斯卡尔算法(MST_Kruskar)
思路,貌似与 bellman·ford算法相似 ,以边集数组的概念存储/枚举每条边
但是要注意:
关键:加边时不能构成回路:边的两个顶点是否已在树中。

void MST_Kruskal()
{
 int c=0;
 sort(a+1,a+m+1,mycmp);
 for(int i=1;i<=m;i++)
 if(!(judge(a[i].v,a[i].u)))
 {
  merge(a[i].v,a[i].u);
  summ=a[i].z;
  if(++c==n-1) break;//只有这边i在最小生成树里时才减
 }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值