思路很简单,就是并查集+kruskal

 1 #include<iostream>
 2 #include<cmath>
 3 #include<algorithm>
 4 #include<cstdio>
 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<i;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 }
View Code

但是如果在判定是否加入边的数组时去掉d<10和d>1000,只在kruskal函数中判定就会WA,不知道为什么,求大神指点

posted on 2019-08-05 11:24  megadeth  阅读(90)  评论(0编辑  收藏  举报