zoukankan      html  css  js  c++  java
  • 最小生成树算法(krustra+prime)

    给你一个图,求让图连通的边权和最小值

    krustra算法是基于加边法,将所有边权排序,每次加一条边,将两个点放在同一个集合中。如果新加的点不在同一个集合中,就合并(并查集)

    涉及到排序,可以用结构体存节点的信息,之后按边权从小到大排序。随后遍历n条边,判断两个节点是否在一个集合中,不在则加入

    int find(int x)
    {
      if(x==father[x])
         return x;
    else
       return find(father[x]);
    }
    bool Union_set(int x,int y)
    { 
      int lx=find(x),ly=find(y);
     if(father[lx]==father[ly])
      return 0;
    else
    {
    father[lx]=ly;
    return 1;
    }
    int krustra()
    {
    for(int i=1;i<=n;i++)
      father[i]=i;
    }
    sort(edge,edge+n,cmp);
    for(int i=1;i<=num;i++)//num为边的总数
    {
      int x=edge[i].lx,y=edge[i].ly;
    if(union_set(x,y))
      ans+=edge[i].value;
    }
    return ans;
    }

    这个问题还可以引申一下,如果只需要将若干个点连通。那么我们在每次做完之后,进行一下判断,判断我们所求的点是否在一个集合中了。(当然可以想象这个时间复杂度会很高)

    Prime算法(加点法,从一个点出发找离他最近的点,然后依次中间点进行更新)

    for(int i=2;i<=n;i++)
       dfs[i]=inf;
    dfs[1]=0;
    while(1)
    {
    int min=inf,pos;
    for(int i=1;i<=n;i++)
    {
     if(!visit[i]&&min>dfs[i])
      min=dfs[i];pos=i;
    }
    if(min==inf)
     break;
    visit[pos]=1; ans+=min;//边权值累加
    for(int j=1;j<=n;j++)
    {
    if(dfs[j]>edge[pos][j])
      dfs[j]=edge[pos][j];
    }
    }
    return ans;
  • 相关阅读:
    Map集合
    Collection的另外一个子类LinkedList&Set集合
    多项式牛顿迭代 学习笔记
    《混凝土数学》第二章 和式 学习笔记
    洛谷P5039 最小生成树 题解
    gdfzoj#236 | 提高组练习题16 Set
    CF979E 题解
    CF1039D 题解
    CF886E 题解
    CF1061C 题解
  • 原文地址:https://www.cnblogs.com/flightless/p/8678439.html
Copyright © 2011-2022 走看看