思路很简单,就是并查集+kruskal
1 #include2 #include 3 #include 4 #include 5 using namespace std; 6 #define MAXN 100001 7 int pre[MAXN],v[MAXN],u[MAXN],r[MAXN],y[MAXN],x[MAXN]; 8 double w[MAXN]; 9 int n,k; 10 int unionfind(int a) 11 { 12 return a==pre[a]?a:pre[a]=unionfind(pre[a]); 13 } 14 bool cmp(int i,int j) 15 { 16 return w[i]<w[j]; 17 } 18 double Distance(int x1,int y1,int x2,int y2) 19 { 20 return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)); 21 } 22 double Kruskal(int m) 23 { 24 sort(r+1,r+m+1,cmp); 25 int cnt=0; 26 double ans=0; 27 for(int i=1;i<=m;i++) 28 { 29 int e=r[i]; 30 if(w[i]>1000||w[i]<10)continue; 31 int x=unionfind(v[e]),y=unionfind(u[e]); 32 if(x!=y) 33 { 34 pre[x]=y; 35 ans+=w[e]; 36 cnt++; 37 } 38 if(cnt==n-1)break; 39 } 40 if(cnt==n-1)return ans; 41 else return -1; 42 } 43 int main() 44 { 45 int t; 46 cin>>t; 47 while(t--) 48 { 49 scanf("%d",&n); 50 for(int i=1;i<=n;i++)pre[i]=i; 51 int cnt=1; 52 for(int i=1;i<=n;i++) 53 { 54 scanf("%d%d",&x[i],&y[i]); 55 for(int j=1;j) 56 { 57 double d=Distance(x[i],y[i],x[j],y[j]); 58 if(d<10||d>1000)continue; 59 v[cnt]=i; 60 u[cnt]=j; 61 r[cnt]=cnt; 62 w[cnt]=d; 63 cnt++; 64 65 } 66 } 67 double ans=Kruskal(cnt-1); 68 if(ans==-1)printf("oh!\n"); 69 else printf("%.1llf\n",double(ans*100)); 70 } 71 }
但是如果在判定是否加入边的数组时去掉d<10和d>1000,只在kruskal函数中判定就会WA,不知道为什么,求大神指点