题目大意:给你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 ",sqrt(minn/(n-1))); 65 } 66 int main(){ 67 int cas; cin>>cas; 68 while(cas--) Main(); 69 }