这题调试了很久,开始自己试图按照自己的理解实现prim算法,但是总是出错。后来参考了网上的算法模板,总算把此题解决。算法模板可以用,但不可以滥用,最好是理解使用的细节,代码库不在多,好用是关键!
基本算法是:修好的路的边权值赋为0,再用prim求最小生成树输出权值。
#include <iostream> #define MAXN 200 #define inf 10000 typedef int elem_t; using namespace std; elem_t prim(int n,elem_t mat[MAXN][MAXN],int* pre){ elem_t min[MAXN],ret=0; int v[MAXN],i,j,k; for (i=0;i<n;i++) min[i]=inf,v[i]=0,pre[i]=-1; for (min[j=0]=0;j<n;j++){ for (k=-1,i=0;i<n;i++) if (!v[i]&&(k==-1||min[i]<min[k])) k=i; for (v[k]=1,ret+=min[k],i=0;i<n;i++) if (!v[i]&&mat[k][i]<min[i]) min[i]=mat[pre[i]=k][i]; } return ret; } int main(){ int n,i,j,result,q,a,b; int pre[MAXN]; int distance[MAXN][MAXN]; cin>>n; for (i = 0;i < n;i++) for (j = 0;j < n;j++) { cin>>distance[i][j]; } cin>>q; for (i = 0;i < q;i++) { cin>>a>>b; distance[a-1][b-1] = 0; distance[b-1][a-1] = 0;//如果某条路已经修好,赋其权值为0 } result = prim(n,distance,pre); cout << result; return 0; }