领接矩阵的各种操作:
https://blog.csdn.net/m0_52103105/article/details/115741225
(里面对普罗里姆的注释会比较详细)
#include <stdio.h>
#include <stdlib.h>
#define N 2022
int arc[N][N];
int money(int x,int y)
{
int a[4]={0};
int b[4]={0};
for(int i=0;i<4;i++)
{
if(x!=0)
a[i]=x%10;
if(y!=0)
b[i]=y%10;
x/=10;
y/=10;
}
int sum=0;
for(int i=0;i<4;i++)
if(a[i]!=b[i])
sum=sum+a[i]+b[i];
return sum;
}
int MiniTree_Prim(int arc[][N])
{
int i,j,k,sum=0;
int locast[N]; //保留前置点到该点i的最小权值
int adjvex[N]; //保留i的前置点
for(i=2;i<N;i++)
{
locast[i]=arc[1][i];
adjvex[i]=1;
}
locast[1]=0;
for(i=2;i<N;i++)
{
int min=2<<27;
j=1;
k=0;
while(j<N)
{
if(locast[j]!=0 && locast[j]<min)
{
min=locast[j];
k=j;
}
j++;
}
sum+=locast[k];
locast[k]=0;
//另一种写法:sum+=arc[adjvex[k]][k]; adjvex是用于输出该结点的父结点用的 题目不需要
for(j=1;j<N;j++)
{
if(locast[j]!=0 && arc[k][j]<locast[j])
{
locast[j]=arc[k][j];
adjvex[j]=k;
}
}
}
return sum;
}
int main()
{
int i,j;
for(i=0;i<N;i++)
for(j=i;j<N;j++)
{
if(i==j)
arc[i][j]=2<<27;
else{
arc[i][j]=money(i,j);
arc[j][i]=money(i,j);
}
}
int ans=MiniTree_Prim(arc);
printf("%d",ans);
return 0;
}