最小生成树

原创 2016年06月01日 22:36:54

一个国家有n个城市。若干个城市之间有电话线连接,现在要增加m条电话线(电话线当然是双向的了),使得任意两个城市之间都直接或间接经过其他城市有电话线连接,你的程序应该能够找出最小费用及其一种连接方案。

输入描述 Input Description

    输入文件的第一行是n的值(n<=100).

    第二行至第n+1行是一个n*n的矩阵,第i行第j列的数如果为0表示城市i与城市j有电话线连接,否则为这两个城市之间的连接费用(范围不超过10000)。

输出描述 Output Description

       输出文件的第一行为你连接的电话线总数m,第二行至第m+1行为你连接的每条电话线,格式为i j,(i<j), i j是电话线连接的两个城市。输出请按照Prim算法发现每一条边的顺序输出,起始点为1.

       第m+2行是连接这些电话线的总费用。

样例输入 Sample Input

5

0 15 27 6 0

15 0 33 19 11

27 33 0 0 17

6 19 0 0 9

0 11 17 9 0

样例输出 Sample Output

2

1 4

2 5

17

借这个题目来说一下prim算法:先任取一个点a,然后找到距离这个点最近的点b,再找距这两个点最近的点c,在更新一下,以a点和b点为基准再找句这两个点最近的点,以此类推。


#include<stdio.h>

int n;
int A[110][110];
int B[110];
int C[110];
int D[110];
int E[110];


int Prim(int n)
{
    int i,p,sum=0,min=-1,mith=0;
    for(i=1;i<=n;i++)B[i]=A[1][i];
    for(i=1;i<=n;i++){E[i]=C[i]=0;D[i]=1;}C[1]=1;E[1]=1;
    for(i=2;i<=n;i++)
        {for(p=1;p<=n;p++)
                {if(B[p]!=-1&&E[p]==0)
                  if(min==-1||B[p]<min)
                    {min=B[p];mith=p;}
                 }
            sum+=min;C[i]=mith;E[mith]=1;
            for(p=1;p<=n;p++)
                {if(A[mith][p]!=-1&&E[p]==0)
                        if(A[mith][p]<B[p]){B[p]=A[mith][p];D[p]=mith;}
                }
            min=-1;mith=0;
         }


    return sum;
    }
int main()
{
    int i,p,t=0,j=0;
    scanf("%d",&n);
    for(i=1;i<=n;i++)
        for(p=1;p<=n;p++)
            {scanf("%d",&A[i][p]);if(i==p)A[i][p]=-1;;
              }
    p=Prim(n);


  for(i=1;i<=n;i++)if(B[i]!=0&&B[i]!=-1)t++;printf("%d\n",t);
    for(i=1;i<=n;i++)
        if(B[C[i]]!=0&&B[C[i]]!=-1){if(C[i]<D[C[i]])printf("%d %d\n",C[i],D[C[i]]);else printf("%d %d\n",D[C[i]],C[i]);}
        printf("%d",p);
    return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。

比较好的题目“典型的最小生成树”

Watering Hole My Tags   (Edit)   Source : USACO 2008 Open  ...
  • struggle_mind
  • struggle_mind
  • 2014年05月07日 21:33
  • 1039

判断最小生成树的唯一性

先用kruskal算法算出最小生成树,并把最小生成树的边记录下来。然后依次枚举删除边,用其他的边再次使用kruskal算法算出最小生成树。如果算出的代价和原来的相同,则不唯一,否则唯一。另外当我们删除...
  • ECNU_LZJ
  • ECNU_LZJ
  • 2016年12月13日 19:38
  • 1561

最小生成树(prim算法与kruskal算法)(模板)

th写的总结,很不错,转载一下:点击打开链接   首先说一下什么是树:     1、只含一个根节点     2、任意两个节点之间只能有一条或者没有线相连     3、任意...
  • zwj1452267376
  • zwj1452267376
  • 2015年08月13日 08:54
  • 1505

最小生成树总结

一.最小生成树问题 给定一张图,图中有许多的节点还有许多长度不同的边将这些点点相互连接,找出连接所有点的最短方式就是最小生成树,可以证明,这样一种最小的情况是不会出现环的,由于所有的无环图都可以看做...
  • u013555159
  • u013555159
  • 2016年05月07日 12:13
  • 847

最小生成树计数-Kruskal+Matrix_Tree定理

/* *算法引入: *给定一个含有N个结点M条边的无向图,求它最小生成树的个数t(G); * *算法思想: *抛开“最小”的限制不看,如果只要求求出所有生成树的个数,是可以利用Matrix-...
  • Jarily
  • Jarily
  • 2013年05月08日 20:55
  • 5858

最小生成树(贪心算法)

最小生成树问题——连接n个针脚,可以使用n-1根连线,每个连线连接两个针脚,使得所使用的连线长度最短     抽象为图问题,一个连通无向图G = (V, E),V是针脚的集合,E是针脚之间的可能连接...
  • huangwwu11
  • huangwwu11
  • 2015年04月15日 23:38
  • 539

贪心算法——Prim最小生成树

1、首先介绍一下什么是贪心算法: 贪心算法(又称贪婪算法)是指,在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,他所做出的是在某种意义上的局部最优解。ps:不懂得话可...
  • baidu_28944591
  • baidu_28944591
  • 2016年06月26日 16:50
  • 1762

最小生成树题集

A题,L题:poj2421 简单题 题意:题目这么长,其实大部分都在扯逼-_-。以字母代替点,每行输入字母,与其相连的个数,以及相连的具体点和其距离,计算全联通最小距离。 题解:只需要把字母距离化...
  • qq_33199236
  • qq_33199236
  • 2016年08月01日 20:21
  • 1551

Bzoj2561:最小生成树:网络流,最小割

题目链接:最小生成树 发现如果这条边可能出现在最大生成树上的话,那么可以代替这条边的所有边都不连通,换句话说这条边是连接u,v必不可少的 于是我们把所有权值大于L的边建成一张边权去为1的图对U,V跑最...
  • qq_34025203
  • qq_34025203
  • 2016年05月03日 21:07
  • 263

hdu 1233 (最小生成树 简单例题)

还是畅通工程 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total S...
  • qq_33406883
  • qq_33406883
  • 2016年07月23日 15:10
  • 1185
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:最小生成树
举报原因:
原因补充:

(最多只允许输入30个字)