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 }
  • 相关阅读:
    函数
    python操作文件
    POJ-2689-Prime Distance(素数区间筛法)
    POJ-2891-Strange Way to Express Integers(线性同余方程组)
    POJ-2142-The Balance
    POJ-1061-青蛙的约会(扩展欧几里得)
    Educational Codeforces Round 75 (Rated for Div. 2) D. Salary Changing
    Educational Codeforces Round 75 (Rated for Div. 2) C. Minimize The Integer
    Educational Codeforces Round 75 (Rated for Div. 2) B. Binary Palindromes
    Educational Codeforces Round 75 (Rated for Div. 2) A. Broken Keyboard
  • 原文地址:https://www.cnblogs.com/mzchuan/p/11828010.html
Copyright © 2011-2022 走看看