最小生成树-

1078 最小生成树

 

 时间限制: 1 s
 空间限制: 128000 KB
 题目等级 : 白银 Silver
 
题目描述 Description

农民约翰被选为他们镇的镇长!他其中一个竞选承诺就是在镇上建立起互联网,并连接到所有的农场。当然,他需要你的帮助。 约翰已经给他的农场安排了一条高速的网络线路,他想把这条线路共享给其他农场。为了使花费最少,他想铺设最短的光纤去连接所有的农场。 你将得到一份各农场之间连接费用的列表,你必须找出能连接所有农场并所用光纤最短的方案。 每两个农场间的距离不会超过100000

输入描述 Input Description

第一行: 农场的个数,N(3<=N<=100)。

第二行..结尾: 接下来的行包含了一个N*N的矩阵,表示每个农场之间的距离。理论上,他们是N行,每行由N个用空格分隔的数组成,实际上,他们每行限制在80个字符以内,因此,某些行会紧接着另一些行。当然,对角线将会是0,因为线路从第i个农场到它本身的距离在本题中没有意义。

输出描述 Output Description

只有一个输出,是连接到每个农场的光纤的最小长度和。

样例输入 Sample Input

4

0  4  9 21

4  0  8 17

9  8  0 16

21 17 16  0

样例输出 Sample Output

28

使用prim算法,可在n^2内解决。其主要思想如下:

1.随意确定一个点,加入一个连通分量;

2.从这个连通分量向外扩展,不断加入离这个连通分量最近的点。

代码如下

 

#include<iostream>
#include<cstdio>
using namespace std;
int _(){      //读入优化
int a=getchar(),ans(0);
while(a<'0')a=getchar();
while(a>='0'&&a<='9') {
ans=ans*10+a-'0';
a=getchar();
}
return ans;
}
int ma[105][105],n,M=0x7fffffff;
int prim(){    //核心代码
int i,j,min,minb,mst[105]={},minc[105]={},sum(0);
for(i=2;i<=n;i++) minc[i]=ma[1][i],mst[i]=1;  //将全部点的最近点确定为点1
mst[1]=0;                    //点1标记为已加
for(i=2;i<=n;i++){
min=M;
minb=0;
for(j=2;j<=n;j++)
if(minc[j]<min&&minc[j]) min=minc[j],minb=j;    //更新最近点
sum+=min;                      //加入最近点的权值
minc[minb]=0;                    //最近点已加
for(j=2;j<=n;j++)
if(ma[minb][j]<minc[j])
minc[j]=ma[minb][j],mst[j]=minb;          //更新离连通分量的权值
}
return sum;
}
int main(){
int i,j;
n=_();
for(i=1;i<=n;i++)
for(j=1;j<=n;j++) ma[i][j]=_();
cout<<prim()<<endl;
}

posted @ 2016-10-13 21:38  wengsy150943  阅读(121)  评论(0)    收藏  举报