求最短路程(Prim算法)求C语言代码的解题
胜利乡有7个村庄(A, B, C, D, E, F, G) ,现在需要修路把7个村庄连通
各个村庄的距离用边线表示(权) ,比如 A–B 距离 5公里
问:如何修路保证各个村庄都能连通,并且总的修建公路总里程最短?
#include <iostream> #define max 10000 using namespace std; int main() { int sum=0;//总路程 int min, min_f , min_t, min_s; //分别为最小值,最小值开始的值,最小值到达的值,顶点之间的边的最小权值 int v[7][7]={{-1,5,7,-1,-1,-1,2},{5,-1,-1,9,-1,-1,3},{7,-1,-1,-1,8,-1,-1},{-1,9,-1,-1,-1,4,-1},{-1,-1,8,-1,-1,5,4},{-1,-1,-1,4,5,-1,6},{2,3,-1,-1,4,6,-1}}; char ch[7] = {'A','B','C','D','E','F','G'}; //-1表示两个点之间没有连线 bool V_[7]; //判断村庄是否路过,标记 for(int i= 0;i<7;i++) //边邻接关系的初始化 { for(int j = 0; j< 7 ;j++) { if(v[i][j]==-1) { v[i][j]=max; } else if(i==j) { v[i][j]=0; } } } V_[0] = true;//从A出发 for(int n = 0;n < 6; n++) //开始遍历7个点 { // 数据初始化 min_f = 0; min_t = 0; min = max; int i,j; for(int i= 0;i<7;i++) //找出发点 { if(!V_[i]) //如果i不是已访问过的结点,则寻找下一个节点 { continue; } for(int i=1;i<=7;i++) //寻找未被收录顶点中的最小值 { if((v[i][j]<min)&&(v[i][j]!=0)) { min_s=v[i][j]; j=i; } } int j; v[i][j]=0; for(int j = 0; j< 7 ;j++) //找到最小边, j表示未访问过的结点 { if(v[i][j] == max) { continue; } if(v[i][j]<min) //如果当前min大于当前两个结点(这两个结点一个为已访问,一个为未访问)的最小路径,则替换当前的最小路径为当前两个结点的路径 { if(V_[j]!=0) { continue; //如果被标记了,跳过。 } min = v[i][j]; min_t = i; min_f = j;//记录下标 } } } cout<<ch[min_t]<<" -> "<<ch[min_f]<<" "<<v[min_t][min_f]<<endl; V_[min_f] = true; sum += v[min_t][min_f]; } cout<<"总路程:"<<sum<<endl; return 0; }