zoukankan      html  css  js  c++  java
  • 次小生成树算法(未完成)

      次小生成树是指在一个树中除最小生成树外第二小的生成树,因此它是在最小生成树算法上衍生的。首先在求出最小生成树后,假如我们要加上一条树外的边,这样就会形成一个闭环,然后将这个闭环的最大

    的边删除,那么剩下的依然是一个树,如果这个树<=最小生成树,那么它就是次小生成树。

      如果我们要加边的话,加的肯定是树外的边,这个用一个标记数组就行,然后我们还要找闭环的最大边值,

    1。secondprim算法

    2.Second_Kruskal算法

      1 struct node
      2 {
      3     //x,y表示边的左右端点,value表示边的值
      4     int x,y,value;
      5     //flag标记边是否在树上
      6     bool flag;
      7 }no[205];
      8 //n表示点数,m表示边数
      9 int n,m;
     10 //fa表示树上的顶点
     11 int fa[105];
     12 //ve用于与第i个点有连接的点
     13 vector<int> ve[105];
     14 //maxn存放两点之间的最大值
     15 int maxn[105][105];
     16 //初始化
     17 void init()
     18 {
     19     //开始时与自己相连的只有自己,同时顶点也是自己
     20     for(int i=0;i<=n;i++)
     21     {
     22         ve[i].clear();
     23         ve[i].push_back(i);
     24         fa[i]=i;
     25     }
     26 }
     27 //查找顶点
     28 int find(int x)
     29 {
     30     //如果找到顶点,则返回
     31     if(fa[x]==x)
     32     {
     33         return x;
     34     }
     35     //递归查找x的上一个点的上一个点,同时压缩路径
     36     return fa[x]=find(fa[x]);
     37 }
     38 //排序,按边的值从小到大
     39 bool cmp(node a,node b)
     40 {
     41     return a.value<b.value;
     42 }
     43 //最小生成树Kruskal算法
     44 int kruskal()
     45 {
     46     //对边进行排序
     47     sort(no+1,no+m+1,cmp);
     48     //初始化数据
     49     init();
     50     //ans表示最小生成树的权值和,cnt表示已经连接的边数
     51     int ans=0,cnt=0;
     52     //遍历所有边
     53     for(int i=1;i<=m;i++)
     54     {
     55         //如果连接了n-1个边,则表示已经连接所有的点了
     56         if(cnt==n-1)
     57         {
     58             break;
     59         }
     60         //记录当前边的两边端点的顶点
     61         int fx=find(no[i].x),fy=find(no[i].y);
     62         //如果他们不相等则进行操作
     63         if(fx!=fy)
     64         {
     65             //将fx的顶点变成fy,相当于把fx这个树的顶点挂在fy这个树顶的下面
     66             fa[fx]=fy;
     67             //生成树的边数加1
     68             cnt++;
     69             //加上这个边的权值
     70             ans+=no[i].value;
     71             //标记这个边
     72             no[i].flag=true;
     73             //对fx,fy则两颗树的所有点遍历
     74             for(int j=0;j<ve[fx].size();j++)
     75             {
     76                 for(int k=0;k<ve[fy].size();k++)
     77                 {
     78                     //将这两可树的所有点之间的最大值都变成现在变的值
     79                     //由于对no进行过排序,因此此时no[i].value的值是这个树上的最大值
     80                     maxn[ve[fx][j]][ve[fy][k]]=maxn[ve[fy][k]][ve[fx][j]]=no[i].value;
     81                 }
     82             }
     83             //对fx的树遍历,将fx树上的点都连在fy树上
     84             for(int j=0;j<ve[fx].size();j++)
     85             {
     86                 ve[fy].push_back(ve[fx][j]);
     87             }
     88         }
     89     }
     90     //如果连了n-1条边则表示有最小生成树
     91     if(cnt==n-1)
     92     {
     93         return ans;
     94     }
     95     else
     96     {
     97         return -1;
     98     }
     99 }
    100 //次小生成树,mst表示最小生成树的权值和
    101 int second_kruskal(int mst)
    102 {
    103     int ans=INF;
    104     //遍历所有边
    105     for(int i=1;i<=m;i++)
    106     {
    107         //如果这个边不在最小生成树上
    108         if(!no[i].flag)
    109         {
    110             //计算最小生成树加外边在减内边否的最小值
    111             ans=min(ans,mst+no[i].value-maxn[no[i].x][no[i].y]);
    112         }
    113     }
    114     return ans;
    115 }
  • 相关阅读:
    [fw]PAGE_SIZE & PAGE_SHIFT & _AC()
    Memory layout of x86_64 in Linux
    Compile Linux Kernel on Ubuntu 12.04 LTS (Detailed)
    ret/retn人为改变执行地址
    [fw]LINUX中断描述符初始化
    查看x86主機是否支援64bit in Linux
    Linux.中断处理.入口x86平台entry_32.S
    [fW]中断处理函数数组interrupt[]初始化
    Linux GNU GAS introduction
    洛谷试炼场 3-5数论 3-17 倍增
  • 原文地址:https://www.cnblogs.com/mzchuan/p/11828010.html
Copyright © 2011-2022 走看看