2 2 10 10 20 20 3 1 1 2 2 1000 1000
1414.2 oh!
一直wa,还不知道原因~~各种修改~才发现距离范围是10~1000.。。。。。
【Kruskal】
AC-code:
#include<cstdio> #include<cmath> #include<algorithm> using namespace std; int per[10005]; struct node { int x,y; }s[10005]; struct nobe { int b,e; double len; }ss[10005]; bool cmp(nobe a,nobe c) { return a.len<c.len; } void pre() { for(int i=0;i<10005;i++) per[i]=i; } int find(int a) { return a==per[a]?a:find(per[a]); } int join(int a,int c) { int fx=find(a); int fy=find(c); if(fx!=fy) { per[fx]=fy; return true; } return false; } int main() { int n,c,i,j,flag; double sum; scanf("%d",&n); while(n--) { scanf("%d",&c); int u; pre(); u=0; sum=0; for(i=0;i<c;i++) scanf("%d%d",&s[i].x,&s[i].y); for(i=0;i<c;i++) for(j=i+1;j<c;j++) { double zz=sqrt((s[i].x-s[j].x)*(s[i].x-s[j].x)+(s[i].y-s[j].y)*(s[i].y-s[j].y)); if(zz>=10&&zz<=1000) { ss[u].b=i; ss[u].e=j; ss[u++].len=zz; } } sort(ss,ss+u,cmp); flag=0; for(i=0;i<u;i++) { if(join(ss[i].b,ss[i].e)) { sum+=ss[i].len; // flag++; } } for(i=0;i<c;i++) if(per[i]==i) flag++; if(flag==1) printf("%.1lf\n",100*sum); else printf("oh!\n"); } return 0; }
【Prim】
AC-code:
#include<cstdio> #include<cstring> #include<cmath> #define max 0x3f3f3f3f double s[110][110]; int n; void prim() { int i,j,k,vis[110]; double min,ans=0,dis[110]; memset(vis,0,sizeof(vis)); for(i=1;i<n;i++) dis[i]=s[0][i]; dis[0]=0; vis[0]=1; for(j=1;j<n;j++) { min=max; k=0; for(i=1;i<n;i++) { if(!vis[i]&&dis[i]<min) { min=dis[i]; k=i; } } if(min==max) { printf("oh!\n"); return ; } ans+=min*100.0; vis[k]=1; for(i=1;i<n;i++) if(!vis[i]&&dis[i]>s[k][i]) dis[i]=s[k][i]; } printf("%.1lf\n",ans); return ; } int main() { int t,x[110],y[110],i,j; scanf("%d",&t); while(t--) { scanf("%d",&n); for(i=0;i<n;i++) scanf("%d%d",&x[i],&y[i]); for(i=0;i<n;i++) for(j=0;j<n;j++) s[i][j]=max; for(i=0;i<n;i++) for(j=0;j<n;j++) { s[j][i]=s[i][j]=sqrt(1.0*((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]))); if(s[j][i]<10||s[j][i]>1000) s[j][i]=s[i][j]=max; } prim(); } return 0; }