题目链接:点击打开链接
题意:求一个图中忽略某个点的最小生成树的最小值
用prim算法求解,要忽略某个点只需在进行prim算法前将这个点的vis[]改为true即可,此时开始prim算法的原点不能是这个点,否则算法将无法继续(没有另一个点初始dis小于inf,无法更新其他点的dis)。
pow函数中两个参数形式需一致,不然会ce。
代码:
#include <iostream> #include <cmath> #include <cstring> #include <cstdio> using namespace std; double a[60][60]; int x[60]; int y[60]; double dis[60]; bool bill[60]; bool vis[60]; int n; const double inf=100000000; double Dis(int x1,int y1,int x2,int y2){ return pow(double((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)),0.5); } double prim(int src){ double res=0; for(int i=1;i<=n;i++){ dis[i]=inf; } dis[src]=0; for(int j=1;j<=n;j++){ double tmp=inf;int k=src; for(int i=1;i<=n;i++){ if(!vis[i]&&dis[i]<tmp){ tmp=dis[i]; k=i; } } vis[k]=1; res+=dis[k]; //cout<<k<<" "<<dis[k]<<" "<<res<<endl; for(int i=1;i<=n;i++){ if(!vis[i]&&dis[i]>a[k][i]){ dis[i]=a[k][i]; } } } return res; } void init(){ memset(vis,0,sizeof(vis)); memset(bill,0,sizeof(bill)); } int main() { int T; cin>>T; while(T--){ double res=100000000; cin>>n; for(int i=1;i<=n;i++){ cin>>x[i]>>y[i]; } for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ a[i][j]=Dis(x[i],y[i],x[j],y[j]); } } for(int i=1;i<=n;i++){ init(); vis[i-1]=0; vis[i]=1; res=min(res,prim(i-1==0?n:i-1)); } printf("%.2lf\n",res); } return 0; }