• 最小生成树模板


    prim算法适合稠密图,其时间复杂度为O(n^2),其时间复杂度与边得数目无关,而kruskal算法的时间复杂度为O(eloge)跟边的数目有关,适合稀疏图。

    一、 普利姆算法(prim)

     1 // 可以输出最短路中的边
     2 #define inf 0x3f3f3f3f
     3 int n,mindis;  //n个顶点 
     4 int map[1000][1000];    // 边的权值 
     5 int vis[1000];          // 标记变量 1表示此下标的顶点已经加入生成树 
     6 int dis[1000];          // 出发点到该下标的权值 
     7 void prim()
     8 {
     9     int i,j,mindis = 0,min,pos;
    10     for(i = 1; i <= n; i ++)
    11     {
    12         dis[i] = map[1][i];
    13         vis[i] = 1;
    14     }
    15     vis[1] = -1;   // 起点已经加入生成树 
    16     for (i = 1; i < n; i ++)  // 循环除起点外的其他顶点 
    17     {
    18         min = inf; pos = -1;
    19         for (j = 1; j <= n; j ++)        // 寻找最小权值 
    20         {
    21             if (vis[j] != -1 && dis[j] < min) 
    22             {
    23                 min = dis[j];
    24                 pos = j;
    25             }
    26         }
    27         if (pos != -1)
    28         {
    29         //    printf("%d  %d
    ",vis[pos],pos);    // 输出加入最短路的边 
    30             mindis += min;
    31             vis[pos] = -1;       // 标记 
    32             for (j = 1; j <= n; j ++)     // 更新权值 
    33                 if (vis[j]!=-1 && dis[j] > map[pos][j])
    34                 {
    35                     dis[j] = map[pos][j];
    36                     vis[j] = pos;
    37                 }
    38         }
    39         
    40     }
    41     printf("%d
    ",mindis);
    42 }
     1 // 只计算最小生成树的权值,不输出构成最小生成树的边,可以将dis数组和vis数组合并
     2 #define inf 0x3f3f3f3f
     3 int map[100][100];
     4 int dis[100];
     5 int n;
     6 void prim()   // 起始点为 1 
     7 {
     8     int i,j,pos,min,sum = 0;
     9     for (i = 1; i <= n; i ++)
    10         dis[i] = map[1][i];
    11     dis[1] = -1;
    12     for (i = 1; i < n; i ++)
    13     {
    14         min = inf; pos = -1;
    15         for (j = 1; j <= n; j ++)
    16         {
    17             if (dis[j] != -1 && dis[j] < min)
    18             {
    19                 pos = j;
    20                 min = dis[j];
    21             }
    22         }
    23         sum += min;
    24         dis[pos] = -1;
    25         for (j = 1; j <= n; j ++)
    26         {
    27             if (map[pos][j] < dis[j])
    28                 dis[j] = map[pos][j];    
    29         } 
    30     }
    31     printf("%d
    ",sum);
    32 }

    一、 克鲁斯卡尔算法(kruskal)

     1 struct point
     2 {
     3     int x,y,l;
     4 }p[11000];
     5 int parent[110],n;
     6 int x[110],y[110];   // 存放边的顶点 
     7 bool cmp(point a, point b)
     8 {
     9     return a.l < b.l;
    10 }
    11 int find(int x)   // 寻找根节点 
    12 {
    13     int s,tmp;
    14     for (s = x; parent[s] >= 0; s = parent[s]);
    15     while (s != x)   // 路径压缩 使后面的查找更快速 
    16     {
    17         tmp = parent[x];
    18         parent[x] = s;
    19         x = tmp;
    20     }
    21     return s;
    22 }
    23 void Union(int A, int B)   // 将两个不同集合的元素合并,使两个集合中任意两个元素都连通 
    24 {
    25     int a = find(A), b = find(B);
    26     int tmp = parent[a]+parent[b];   // 和为负数 
    27     if (parent[a] < parent[b])
    28     {
    29         parent[b] = a;
    30         parent[a] = tmp;
    31     }
    32     else
    33     {
    34         parent[a] = b;
    35         parent[b] = tmp;
    36     }
    37 } 
    38 void kruskal(int 边数)
    39 {
    40     int sum = 0;
    41     int u,v,i,j = 0;
    42     sort(p,p+边数,cmp);
    43     memset(parent,-1,sizeof(parent));
    44     for (i = 0; i <= k; i ++)
    45     {
    46         u = p[i].x;    v = p[i].y;
    47         if (find(u) != find(v))
    48         {
    49             sum += p[i].l;
    50             Union(u,v);
    51             j ++;
    52         }
    53         if (j == n-1) break;
    54     }
    55     printf("%d
    ",sum);
    56 }

    算法理解: http://www.cnblogs.com/yoke/p/6506492.html

  • 相关阅读:
    Android UI--自定义ListView(实现下拉刷新+加载更多)
    12306火车票订票网站的一个Bug
    golang中赋值string到array
    Node.js学习(14)----EJS模板引擎
    操作系统
    springMVC学习笔记--初识springMVC
    sqlplus 连接数据库报错SP2-0642: SQL*Plus internal error state 2130, context 0:0:0
    对于事务和同步(并发)的简要理解
    Jsoup入门
    [LeetCode]Single Number
  • 原文地址:https://www.cnblogs.com/yoke/p/6506307.html
Copyright © 2020-2023  润新知