注意n個點有n-1條邊就ok
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;int n;char a[502][10];int b[502][5] = {0};int map[502][502];int dis[502];bool flag[502];int result;int mi(int i, int j){ int sum = 0; int temp; for(int k = 1; k <= 4; k++){ temp = abs( b[i][k] - b[j][k]); if(temp > 5) temp = 10 - temp; sum += temp; } return sum;}void prim (){ int i,j; int mark; result=0; memset(flag,false,sizeof(flag)); flag[1]=true; for(i=1;i<=n;i++) { dis[i]=map[1][i]; } for(i=1;i<n;i++)//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! { int min=999999999; for(j=2;j<=n;j++) { if(!flag[j]&&dis[j]<=min) { min=dis[j]; mark=j; } } flag[mark]=true;result+=dis[mark]; for(j=2;j<=n;j++) { if(!flag[j]&&map[mark][j]<dis[j]) dis[j]=map[mark][j]; } }}int main(){ int t; scanf("%d",&t); while(t--){ memset(map ,0, sizeof(map)); scanf("%d",&n); for(int i = 1;i <= n;i++){ scanf("%s",a[i]); for(int j = 0;j < 4;j++){b[i][j+1] = a[i][j] -'0'; } } for(int i = 0;i < n;i++){ for(int j = i + 1;j <= n;j++){map[j][i] = map[i][j] = mi(i ,j); } } prim(); int min1 =9999999; for(int i = 1;i <= n;i++)if(map[0][i] < min1)min1 = map[0][i]; result += min1; printf("%d\n",result); }}