刚学最小树,理解不算难,只是敲起来有点慢,这个题也不算复杂只是没有直接告诉你节点和权值而已,你自己算一下存起来然后还是最小树的基本题型,代码如下:
#include<stdio.h> #include<string.h> #include<stdlib.h> #include<math.h> #include<iostream> #include<time.h> #include<map> #include<ctype.h> #include<queue> #include<stack> #include<algorithm> using namespace std; int f[30003]; void in(int n) { int i; for(i=0; i<=n; i++) f[i]=i; } int fd(int x) { if(f[x]==x) return x; return f[x]=fd(f[x]); } struct DD { int n1,n2; int x,y; double w; } A[300003]; bool cmp(DD a,DD b) { return a.w<b.w; } int main() { int t,n,i,j,k; scanf("%d",&t); while(t--) { int h=0; int cou=0; double sum=0; scanf("%d",&n); in(n); for(i=0; i<n; i++) scanf("%d%d",&A[i].x,&A[i].y);//存坐标 for(i=0; i<n-1; i++) { for(j=i+1; j<n; j++) { A[h].n1=i;//此处是存两个节点,就是相连的顶点 A[h].n2=j; A[h].w=sqrt((A[i].x-A[j].x)*(A[i].x-A[j].x)+(A[i].y-A[j].y)*(A[i].y-A[j].y));//边的权值 h++; } } sort(A,A+h,cmp); for(i=0; i<h; i++) { int xx=fd(A[i].n1); int yy=fd(A[i].n2); if(A[i].w<10)//本来这两个地方判断条件弄得很细但是过不去,给条件放宽就过了 continue; if(A[i].w>1000) break; if(xx!=yy) { f[xx]=yy; sum+=A[i].w; cou++; } if(cou==n-1) break; } if(cou==n-1) printf("%.1f\n",sum*100); else printf("oh!\n"); } }