题意:某省调查乡村交通状况,得到的统计表中列出了任意两村庄间的距离。省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可),并要求铺设的公路总长度为最小。请计算最小的公路总长度。
思路:prim算法,从任一i点开始,找出最短相邻边,将k点加入自己,遍历该点有关的所有边,跟新i点与其他点的距离,寻找下一个k点直到遍历结束。
1 #include<iostream> 2 #include<string.h> 3 using namespace std; 4 const int N=105; 5 const int INF=0x3f3f3f3f; 6 int n,m;//n个点,m条边 7 int map[N][N];//存储每条边 8 int vis[N],dis[N]; 9 int ans,k; 10 void prim(){ 11 //点1到每条边的距离 12 for(int i=1;i<=n;++i){ 13 dis[i]=map[1][i]; 14 } 15 vis[1]=1; 16 for(int i=2;i<=n;++i){ 17 int min=INF; 18 for(int j=1;j<=n;++j){ 19 if(!vis[j]&&min>dis[j]){ 20 min=dis[j]; 21 k=j; 22 } 23 } 24 vis[k]=1; 25 ans+=min; 26 for(int j=1;j<=n;++j){ 27 if(!vis[j]&&dis[j]>map[k][j]){ 28 dis[j]=map[k][j]; 29 } 30 } 31 } 32 } 33 int main() { 34 ios::sync_with_stdio(false); 35 while(scanf("%d",&n)&&n){ 36 m=n*(n-1)/2; 37 memset(vis,0,sizeof(vis)); 38 for(int i=1;i<=100;++i){ 39 for(int j=1;j<=100;++j){ 40 if(i==j){ 41 map[i][j]=0; 42 } 43 else{ 44 map[i][j]=INF; 45 } 46 } 47 } 48 for(int i=1;i<=m;++i){ 49 int u,v,w; 50 scanf("%d %d %d",&u,&v,&w); 51 if(map[u][v]>w){ 52 map[u][v]=w; 53 map[v][u]=w; 54 } 55 } 56 ans=0; 57 prim(); 58 printf("%I64d ",ans); 59 } 60 61 return 0; 62 }