原题就是输入所有 i 到j 的距离 求最小生成树 和次小生成树 自己手写的: prim 算法 : 不知道kruskal算法应该怎么实现得好 #include<iostream> #include<cstring> #include<cstdio> #include<vector> using namespace std; #define INF 999999999 int n_village; #define N 1003 int dist[N][N]; int tmp; int max_dist[N][N]; int d[N]; int res=0; int used[N]; int fa[N]; vector <int> node; int flag[N][N]; void prim(); int main() { freopen("in.txt","r",stdin); while(cin>>n_village) { memset(flag,0,sizeof(flag)); memset(max_dist,0,sizeof(max_dist)); memset(used,0,sizeof(used)); res=0; node.clear(); for(int i=0;i<n_village;i++) for(int j=0;j<n_village;j++) { scanf("%d",&dist[i][j]); } prim(); int min_dist=INF; cout<<res<<endl; for(int i=0;i<n_village;i++) for(int j=0;j<i;j++) if(!flag[i][j]) { if(min_dist>dist[i][j]-max_dist[i][j]) min_dist=dist[i][j]-max_dist[i][j]; } cout<<res+min_dist<<endl; } } void prim() { for(int i=0;i<n_village;i++) d[i]=INF; d[0]=0; fa[0]=0; for(int i=0;i<n_village;i++) { int min_tmp=INF; int id; for(int j=0;j<n_village;j++) { if(!used[j]&&d[j]<min_tmp) { min_tmp=d[j];id=j; } } if(min_tmp==INF) break; // cout<<id<<endl; used[id]=1; res+=d[id]; flag[fa[id]][id]=flag[id][fa[id]]=1; for(int t=0;t<node.size();t++) { int z=node[t]; int tt=max(max_dist[z][fa[id]],d[id]); max_dist[z][id]=max_dist[id][z]=tt; } node.push_back(id); for(int j=0;j<n_village;j++) { if(!used[j]&&d[j]>dist[id][j]) { d[j]=dist[id][j]; fa[j]=id; } } } }