zoukankan      html  css  js  c++  java
  • 最小生成树 kruskal 和 pime 模版

    kruskal:

    View Code
      1 #include <iostream>
      2 #define INF 0x3fff
      3 #define MAXN 100
      4 using namespace std;
      5 typedef struct
      6 {
      7     int s;//start结点 
      8     int e;//end结点 
      9     int w;//weight权值 
     10 }edge;
     11 edge e[MAXN*MAXN/2];//存储每一条边的数组 
     12 void insertsort(edge e[],int n)//直接插入排序 
     13 {
     14     int i,j;
     15     edge temp;
     16     for(i = 0 ; i < n ;i++)
     17     {
     18         temp = e[i];
     19         j = i - 1;
     20         while(j >= 0 && temp.w < e[j].w)
     21         {
     22             e[j+1]= e[j];
     23             j--;
     24         }
     25         e[j+1] = temp;
     26     }
     27 }
     28 void kruskal(int n,int mat[][MAXN])//Kruskal实现 
     29 {
     30     int i,j,k,m1,m2,sn1,sn2;
     31     edge e[MAXN*MAXN/2];
     32     int vset[MAXN];
     33     for(i = 0 ; i < n ; i++)//每个节点都初始化 
     34         vset[i] = i;
     35     k = 0;
     36  
     37     for(i = 0 ; i < n;i++)
     38     {
     39         for(j = 0 ; j < n;j++)
     40         {
     41             if(mat[i][j] != 0 && mat[i][j] != INF)//将邻接矩阵中的每一条边都加入到边权值的数组中 
     42             {
     43                 e[k].s = i;e[k].e = j;
     44                 e[k].w = mat[i][j];
     45                 k++;
     46             }
     47         }
     48     }
     49     insertsort(e,k);//对边的权值从大到小排序,这里采用直接插入排序,如果采用堆排序时间复杂度会减少 
     50     int cnt = 1 ;//记录加入到最小生成树的边的数量 
     51     k = 0;
     52     while(cnt < n)
     53     {
     54         m1 = e[k].s; m2 = e[k].e;//记录这条边的start , end 结点 
     55         sn1 = vset[m1]; sn2 = vset[m2];//看这两个结点属于哪一个set 
     56         if(sn1 != sn2)//如果不等,说明这两个结点不在一个生成树中,合并 
     57         {
     58             printf("edge (%d,%d):%d is added!\n", e[k].s,e[k].e,e[k].w);
     59             cnt++;
     60             for(i = 0 ; i < n ; i++)
     61             {
     62                 if(vset[i] == sn2)//把所有的原有的生成树的结点重新加入到新的生成树中 
     63                     vset[i] = sn1;
     64             }
     65         }
     66         k++;//k为边的权值数组的Index 
     67     }   
     68  
     69 }
     70 int mat[MAXN][MAXN];
     71 int main()
     72 {
     73     memset(mat,0,sizeof(mat));
     74     int num;
     75     printf("please input vertex:");
     76     scanf("%d",&num);
     77     int n;
     78     printf("input the number of edge:");
     79     scanf("%d",&n);
     80     int t = n;
     81     while(t--)
     82     {
     83         int a,b,cost;
     84         scanf("%d %d %d",&a,&b,&cost);
     85         --a,--b;
     86         if(mat[a][b] == 0 && mat[b][a] == 0 || cost < mat[a][b] )
     87             mat[a][b] = mat[b][a] = cost;
     88     }
     89     int i,j;
     90     for(i = 0 ; i < num;i++){
     91         for(j = 0 ; j < num; j++)
     92             printf("%4d",mat[i][j]);printf("\n");}
     93     kruskal(num,mat);
     94 /*
     95 test data:
     96 6
     97 10
     98 1 2 6
     99 1 3 1
    100 1 4 5
    101 2 3 5
    102 3 4 5
    103 2 5 3
    104 3 5 6
    105 3 6 4
    106 4 6 2
    107 5 6 6
    108 */ 
    109     return 0;
    110 }

    更简洁的Kruskal模板:

    View Code
     1 #include"iostream"
     2 #include"cstdio"
     3 #include"cstdlib"
     4 #include"algorithm"
     5 using namespace std;
     6 struct node
     7 {
     8     int x,y,l;//分别表示两条边的顶点,及距离
     9 }road[1200];
    10 int pre[20];
    11 int find( int x )
    12 {
    13     int r=x;
    14     while( pre[r]!=r )
    15         r=pre[r];
    16     int i=x;
    17     int j;
    18     while( i!=r )
    19     {
    20         j=pre[i];
    21         pre[i]=r;
    22         i=j;
    23     }
    24     return r;
    25 }
    26 
    27 bool cmp( struct node m,struct node n )
    28 {
    29     return m.l<n.l;
    30 }
    31 
    32 int main()
    33 {
    34 
    35 //    freopen("input.txt","r",stdin);
    36 //    freopen("output.txt","w",stdout);
    37     int n;
    38     while( scanf("%d",&n)!=EOF )
    39     {
    40         int i;
    41         for( i=0;i<=n;i++ )
    42             pre[i]=i;//初始化所有点都是孤立的
    43         int k;
    44         for( i=0;;i++ )
    45         {
    46             scanf("%d%d%d",&road[i].x, &road[i].y,&road[i].l);
    47             k=i;
    48             if( !road[i].x && !road[i].y && !road[i].l )
    49                 break;
    50         }
    51         sort( &road[0],&road[k+1],cmp );
    52         int ans=road[0].l;
    53         pre[road[0].x]=road[0].y;
    54         for( i=1;i<=k;i++ )
    55         {
    56             if( find( road[i].x)!=find(road[i-1].x) || find( road[i].y )!=find( road[i-1].x ) )
    57             {
    58                 ans+=road[i].l;
    59                 pre[road[i].x]=find( road[i-1].x );
    60                 pre[road[i].y]=find( road[i-1].x );
    61             }
    62         }
    63         printf("%d\n",ans);
    64 
    65     }
    66     return 0;
    67 }

    prime 模板:

    View Code
     1 #define MAXN
     2 bool flag[MAXN];
     3 double graph[MAXN][MAXN];   // graph[i][j] 表示节点i到j的距离
     4  
     5 double Prim(int n)  // 一共n个节点
     6 {
     7     int i, j, k;
     8     double t, lowcase[105], ans = 0;
     9     for (i = 2; i <= n; i++)
    10         lowcase[i] = graph[1][i], flag[i] = false;
    11     flag[1] = true;
    12  
    13     for (i = 1; i < n; i++)
    14     {
    15         k = 1;
    16         t = INF;
    17         for (j = 2; j <= n; j++)
    18             if (!flag[j] && lowcase[j] < t)
    19                 k = j, t = lowcase[j];
    20          
    21         ans += t;
    22         flag[k] = true;
    23  
    24         for (j = 1; j <= n; j++)
    25             if (!flag[j] && graph[k][j] < lowcase[j])
    26                 lowcase[j] = graph[k][j];
    27     }
    28  
    29     return ans;
    30 }
  • 相关阅读:
    2018年你需要知道的13个JavaScript工具库
    JavaScript一团乱,这是好事
    5大JavaScript前端框架简介
    大型Vuex应用程序的目录结构
    Github被微软收购,这里整理了16个替代品
    如何使用@vue/cli 3.0在npm上创建,发布和使用你自己的Vue.js组件库
    TensorFlow入门教程
    想成为顶级开发者吗?亲自动手实现经典案例
    2018年最值得关注的30个Vue开源项目
    SQL Server 合并复制遇到identity range check报错的解决 (转载)
  • 原文地址:https://www.cnblogs.com/shenshuyang/p/2623612.html
Copyright © 2011-2022 走看看