双向边,基础题,最小生成树
#define _CRT_SECURE_NO_WARNINGS #include #include #include #include #include #include using namespace std; #define inf 999999999 #define M 110 int mat[M][M]; int prim(int n,int sta) { int mark[M],dis[M]; int i,sum=0,j; for(i=0;i { dis[i]=mat[sta][i]; mark[i]=0; } mark[sta]=1; for(i=0;i { int minn=inf,flag=-1;; for(j=0;j { if(mark[j]==0&&dis[j] { minn=dis[j]; flag=j; } } if(flag!=-1) { mark[flag]=1; sum=sum+dis[flag]; for(j=0;j { if(dis[j]>mat[flag][j]) dis[j]=mat[flag][j]; } } } return sum; } int main() { int n,i,j,m,adj; char s,e; while(scanf("%d",&n),n) { for(i=0;i for(j=0;j mat[i][j]=inf; n--; for(i=0;i { cin>>s>>m; for(j=0;j { cin>>e>>adj; mat[s-‘A‘][e-‘A‘]=mat[e-‘A‘][s-‘A‘]=adj;//擦,原来这题的最小生成树也是双向边 } } n++; printf("%d\n",prim(n,0)); } return 0; }
//关键代码参考自模版: //prim算法(矩阵形式): #define inf 0x3f3f3f3f int prim(int n,int sta)//n表示有n个顶点,sta表从sta这个顶点出发生成最小生成树 { int mark[M],dis[M]; int i,sum = 0; //sum是总的最小生成树边权值 for (i = 0;i < n;i ++) //初始化dis[i] 表从顶点sta到点i的权值 { dis[i] = mat[sta][i]; mark[i] = 0; } mark[sta] = 1; //sta 这个顶点加入最小生成树中 for (i = 1;i < n;i ++) //循环n-1次,每次找出一条最小权值的边 n个点的图 { //只有n-1条边 int min = inf; //inf 表无穷大 for (j = 0;j < n;j ++)//找出当前未在最小生成树中边权最小的顶点 if (!mark[j] && dis[j] < min) min = dis[j],flag = j; mark[flag] = 1; //把该顶点加入最小生成树中 sum += dis[flag]; //sum加上其边权值 for (j = 0;j < n;j ++) //以falg为起点更新到各点是最小权值 if (dis[j] > mat[flag][j]) dis[j] = mat[flag][j]; } return sum; //返回边权总和 }