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

    标题: Prim和Kruskal最小生成树
    时 限: 2000 ms
    内存限制: 15000 K
    总时限: 3000 ms
    描述: 给出一个矩阵,要求以矩阵方式单步输出生成过程。
    要求先输出Prim生成过程,再输出Kruskal,每个矩阵输出后换行。
    注意,题中矩阵表示无向图
    输入: 结点数
    矩阵
    输出: Prim:
    矩阵输出
    Kruskal:
    矩阵输出
    输入样例:
    3

    0 1 3

    1 0 2

    3 2 0

    输出样例:
    3


    0 1 3

    1 0 2

    3 2 0
    Prim:

    0 0 0

    0 0 0

    0 0 0

    0 1 0

    1 0 0

    0 0 0

    0 1 0

    1 0 2

    0 2 0

    Kruskal:

    0 0 0

    0 0 0

    0 0 0

    0 1 0

    1 0 0

    0 0 0

    0 1 0

    1 0 2

    0 2 0

    提示: Kruskal 中的边集合应用拓扑排序的想法排除环
    来源: 教材P170-179

      1 //2016.10.25
      2 #include <iostream>
      3 #include <cstdio>
      4 #include <cstring>
      5 #include <algorithm>
      6 #define N 200
      7 
      8 using namespace std;
      9 
     10 struct Edge
     11 {
     12     int u, v, c;
     13     bool operator<(Edge x){
     14         return c < x.c;
     15     }
     16 }edge[100005];
     17 int G[N][N], T[N][N], n, cnt, fa[N];
     18 
     19 void print(int T[][N])
     20 {
     21     for(int i = 1; i <= n; i++){
     22         for(int j = 1; j <= n; j++){
     23             printf("%d ", T[i][j]);
     24         }
     25         printf("
    ");
     26     }
     27     printf("
    ");
     28 }
     29 
     30 void init(int n)
     31 {
     32     for(int i = 1; i <= n; i++)
     33           fa[i] = i;
     34 }
     35 
     36 int getfa(int x)
     37 {
     38     if(fa[x] == x) return x;
     39     return fa[x] = getfa(fa[x]);
     40 }
     41 
     42 void myUnion(int a, int b)
     43 {
     44     int af = getfa(a);
     45     int bf = getfa(b);
     46     if(af != bf)fa[bf] = af;
     47 }
     48 
     49 void prim()
     50 {
     51     int book[N], uf, vf;
     52     memset(T, 0, sizeof(T));
     53     memset(book, 0, sizeof(book));
     54     print(T);
     55     sort(edge, edge+cnt);
     56     init(n);
     57     int cntv = 1;
     58     int parent = edge[0].u;
     59     while(cntv < n)
     60     {
     61         for(int i = 0; i < cnt; i++)
     62         {
     63             if(book[i])continue;
     64             uf = getfa(edge[i].u);
     65             vf = getfa(edge[i].v);
     66             if((uf == parent || vf == parent) && uf != vf)
     67             {
     68                 myUnion(parent, uf);
     69                 myUnion(parent, vf);
     70                 book[i] = 1;
     71                 T[edge[i].u][edge[i].v] = T[edge[i].v][edge[i].u] = edge[i].c;
     72                 print(T);
     73                 cntv++;
     74                 break;
     75             }
     76         }
     77     }
     78     return ;
     79 }
     80 
     81 void kruskal()
     82 {
     83     sort(edge, edge+cnt);
     84     int book[N], uf, vf;
     85     init(n);
     86     memset(book, 0, sizeof(book));
     87     memset(T, 0, sizeof(T));
     88     print(T);
     89     for(int i = 0; i < cnt; i++)
     90     {
     91         uf = getfa(edge[i].u);
     92         vf = getfa(edge[i].v);
     93         if(uf != vf)
     94         {
     95             T[edge[i].u][edge[i].v] = T[edge[i].v][edge[i].u] = edge[i].c;
     96             myUnion(edge[i].u, edge[i].v);
     97             book[edge[i].u] = book[edge[i].v] = 1;
     98             print(T);
     99         }
    100         int sum = 0;
    101         for(int i = 1; i <= n; i++){
    102             if(fa[i] == i)sum++;
    103             if(sum > 1)break;
    104         }
    105         if(sum==1)break;
    106     }
    107     return;
    108 }
    109 
    110 int main()
    111 {
    112     cnt = 0;
    113     scanf("%d", &n);
    114     for(int i = 1; i <= n; i++)
    115           for(int j = 1; j <= n; j++)
    116           {
    117               scanf("%d", &G[i][j]);
    118               if(i < j && G[i][j] != 0)
    119               {
    120                   edge[cnt].u = i;
    121                   edge[cnt].v = j;
    122                   edge[cnt].c = G[i][j];
    123                   cnt++;
    124               }
    125           }
    126     printf("Prim:
    ");
    127     prim();
    128     printf("Kruskal:
    ");
    129     kruskal();
    130 
    131     return 0;
    132 }
  • 相关阅读:
    【编程练习】poj1111
    Android项目开发填坑记-Fragment的onBackPressed
    【编程练习】poj1068
    HTML DOCTYPE文档类型举例说明
    css link import
    css position relative obsolution
    UL/LI
    背离
    stock 当天盘势
    stock 仓位
  • 原文地址:https://www.cnblogs.com/Penn000/p/6002048.html
Copyright © 2011-2022 走看看