【xsy1303】生成树 乱搞

题目大意:给你n个点,问这n个点构成的最小标准差生成树的值

这题题解里面写的都是什么代码??

你用O(n^4)的复杂度,枚举出两条边,然后求平均数。

对于剩下的边,我们求出这些边与平均数的差,然后求最下差生成树。

然后就过了???

不是很懂

 1 #include<bits/stdc++.h>
 2 #define M 22
 3 #define sqr(x) ((x)*(x))
 4 using namespace std;
 5 
 6 double x[M]={0},y[M]={0},dis[M][M]={0}; int n;
 7 
 8 int m=0;
 9 
10 struct edge{
11     int u,v; double w;
12     friend bool operator <(edge a,edge b){return a.w<b.w;}
13 }a[M*M]; bool sel[M*M]={0};
14 
15 int f[M]={0}; int get(int x){return x==f[x]?x:f[x]=get(f[x]);}
16 
17 map<double,int> mp; 
18 
19 double solve(double avg){
20     if(mp[avg]) return 459354345739875984; mp[avg]=1;
21     memset(sel,0,sizeof(sel));
22     for(int i=1;i<=n;i++) f[i]=i;
23     m=0;
24     for(int i=1;i<=n;i++)
25     for(int j=i+1;j<=n;j++)
26     a[++m]={i,j,sqr(dis[i][j]-avg)};
27     sort(a+1,a+m+1);
28     double sum=0;
29     for(int i=1;i<=m;i++){
30         int U=get(a[i].u),V=get(a[i].v);
31         if(U==V) continue;
32         sel[i]=1;
33         f[U]=V;
34     }
35     for(int i=1;i<=m;i++) if(sel[i]){
36         sum+=dis[a[i].u][a[i].v];
37     }
38     avg=sum/(n-1); sum=0;
39     for(int i=1;i<=m;i++) if(sel[i]){
40         sum+=sqr(avg-dis[a[i].u][a[i].v]);
41     }
42     return sum;
43 }
44     
45 
46 int Main(){
47     scanf("%d",&n);
48     for(int i=1;i<=n;i++) scanf("%lf",x+i);
49     for(int j=1;j<=n;j++) scanf("%lf",y+j);
50     for(int i=1;i<=n;i++)
51     for(int j=1;j<=n;j++)
52     dis[i][j]=sqrt(sqr(x[i]-x[j])+sqr(y[i]-y[j]));
53     
54     double minn=123456789000000;
55     for(int i1=1;i1<=n;i1++)
56     for(int j1=1;j1<=n;j1++) if(i1!=j1){
57         double dis1=dis[i1][j1];
58         for(int i2=1;i2<=n;i2++)
59         for(int j2=1;j2<=n;j2++) if(i2!=j2){
60             double dis2=dis[i2][j2];
61             minn=min(minn,solve((dis1+dis2)/2));
62         }
63     }
64     printf("%.3lf\n",sqrt(minn/(n-1)));
65 }
66 int main(){
67     int cas; cin>>cas;
68     while(cas--) Main();
69 }

猜你喜欢

转载自www.cnblogs.com/xiefengze1/p/10651187.html