zoukankan      html  css  js  c++  java
  • 最小生成树

    最小生成树问题,可以用克鲁斯卡尔算法和普利姆算法,Prim最主要的思想是根据顶点来得出结果,而Kruscal则是根据边来得出结果的,因此Prim最要运用于稠密图的计算,而Kruskal主要是运用于稀疏图的计算。因为只能选择一个楼连接到外界供电设备,所以只要构成最小生成树的边的和加上与外界连接花费最小的值就可以。

    Kruskal:算法第一步是给所有边按从小到大排序

                             第二步初始化最小生成树为空,(初始化连通分量,每个点自成一个独立的连通分量,所以初始状态有多少顶点就有多少连通分量)

                             第三步按照排列好的顺序,如果两条边不在同一个连通分量,将这两条边合并为同一个连通分量;如果两条边在同一个连通分量里,那么如果再进行连通处理会形成环,所以不能选择。

                            第四步最小生成树的边的个数是顶点个数减一,可以通过这个来判断生成树是否正确。

    传送门:

     1 #include <cstdio>
     2 #include <cstdlib>
     3 #include <cstring>
     4 #include <algorithm>
     5 using namespace std;
     6 struct node {
     7     int x,y;
     8     int w;
     9 };
    10 node s[250000];
    11 int f[510];//表示各个顶点在不同的分量(即所属父亲)
    12 int sum;//记录最小的花费
    13 int v,e,n;
    14 int ss[510];//楼的花费
    15 
    16 int cmp(node a,node b)
    17 {
    18     return a.w<b.w;
    19 }
    20 void kruscal()//kruscal 入口 
    21 {
    22     int q;   
    23     for(int i=0;i<=v;i++)
    24         f[i]=i;
    25     sort(s,s+e,cmp);
    26     int num=1,j;  //记录边的个数 
    27     int k=0;//循环边的下标 
    28     while(num<v)
    29     {
    30         if(f[s[k].x]!=f[s[k].y]) //判断这条边是否构成回路 
    31         {
    32             num++;
    33             sum+=s[k].w;
    34             q=f[s[k].y];
    35             for(j=1;j<=v;j++)//循环每个和q相等的顶点父亲 .
    36             {
    37                 if(f[j]==q)    f[j]=f[s[k].x];
    38             }
    39         }
    40         k++;//循环每条边 
    41     }
    42 }        
    43 int main()
    44 {
    45     scanf("%d",&n);
    46     while(n--)
    47     {
    48         sum=0;
    49         scanf("%d%d",&v,&e);
    50         for(int i=0;i<e;i++)
    51             scanf("%d%d%d",&s[i].x,&s[i].y,&s[i].w);
    52         for(int i=0;i<v;i++)
    53             scanf("%d",ss+i);
    54         sort(ss,ss+v);
    55         kruscal();
    56         printf("%d
    ",sum+ss[0]);
    57     }
    58     return 0;
    59 }
    60 
    61         
    krusckal
     1 #include <cstdio>
     2 #include <cstring>
     3 using namespace std;
     4 
     5 int sum;
     6 bool vis[510];//标志是否添加到生成点
     7 int map[501][501];
     8 int des[510]; //生成的点到未生成的点距离
     9 
    10 void init(int v)
    11 {
    12     int i,j;
    13     for(i=0;i<=v;i++)
    14     {
    15         for(j=0;j<=v;j++)
    16             map[i][j]=99999999;
    17     }
    18 }
    19 
    20 void prim(int v,int e)
    21 {
    22     int i,j;
    23     memset(vis,0,sizeof(vis));
    24     for(i=1;i<=v;i++)
    25         des[i]=map[1][i];
    26     vis[1]=1;
    27     des[1]=0;
    28     int num=1;
    29     while(num<v)
    30     {
    31         int min=99999999,k;
    32         for(i=2;i<=v;i++)
    33         {
    34             if(des[i]<min&&vis[i]==0)
    35             {
    36                 min=des[i];
    37                 k=i;
    38             }
    39         }
    40             sum+=min;
    41             vis[k]=1;
    42             num++;
    43             for(i=2;i<=v;i++)
    44             {
    45                 if(map[k][i]<des[i]&&vis[i]==0)
    46                     des[i]=map[k][i];
    47             }
    48     }
    49 }
    50 int main()
    51 {
    52     int n,v,e;
    53     scanf("%d",&n);
    54     while(n--)
    55     {
    56         sum=0;
    57         scanf("%d%d",&v,&e);
    58         init(v);
    59         int i,a,b,c;
    60         for(i=0;i<e;i++)
    61         {
    62             scanf("%d%d%d",&a,&b,&c);
    63             if(map[a][b]>c)
    64                 map[a][b]=map[b][a]=c;
    65         }
    66         int t=99999999;
    67         for(i=0;i<v;i++)
    68         {
    69             scanf("%d",&a);
    70             if(t>a)
    71                 t=a;
    72         }
    73         prim(v,e);
    74         printf("%d
    ",sum+t);
    75     }
    76     return 0;
    77 }
    prim
  • 相关阅读:
    Linux中的邮件发送
    Python学习笔记18-发送邮件
    Ansible学习笔记
    eclipse使用maven打包时去掉测试类
    CentOS安装redis
    spring boot 部署
    sprint boot 配置
    spring-boot 学习笔记一
    不要容忍破窗户
    阿里云安装Oracle
  • 原文地址:https://www.cnblogs.com/WDKER/p/5464960.html
Copyright © 2011-2022 走看看