【最小生成树】畅通工程再续
畅通工程再续
Time Limit : 2000/1000ms (Java/Other) Memory Limit : 32768/32768K (Java/Other)
Total Submission(s) : 16 Accepted Submission(s) : 12
Problem Description
相信大家都听说一个“百岛湖”的地方吧,百岛湖的居民生活在不同的小岛中,当他们想去其他的小岛时都要通过划小船来实现。现在政府决定大力发展百岛湖,发展首先要解决的问题当然是交通问题,政府决定实现百岛湖的全畅通!经过考察小组RPRush对百岛湖的情况充分了解后,决定在符合条件的小岛间建上桥,所谓符合条件,就是2个小岛之间的距离不能小于10米,也不能大于1000米。当然,为了节省资金,只要求实现任意2个小岛之间有路通即可。其中桥的价格为 100元/米。
Input
输入包括多组数据。输入首先包括一个整数T(T <= 200),代表有T组数据。 每组数据首先是一个整数C(C <= 100),代表小岛的个数,接下来是C组坐标,代表每个小岛的坐标,这些坐标都是 0 <= x, y <= 1000的整数。
Output
每组输入数据输出一行,代表建桥的最小花费,结果保留一位小数。如果无法实现工程以达到全部畅通,输出”oh!”.
Sample Input
2
2
10 10
20 20
3
1 1
2 2
1000 1000
2
10 10
20 20
3
1 1
2 2
1000 1000
Sample Output
1414.2
oh!
oh!
Author
8600
Source
2008浙大研究生复试热身赛(2)——全真模拟
题目大意:
输入T,表示有T组数据,每一组数据先输入N,表示有N个点,然后下面有N行,每一行分别输入地1~N的坐标(x,y),然后要在这些点直接建桥,桥的长度不能小于10且不能够大于1000,问你连接着N个点,所需要建桥的长度总和的最小值(*100)。如果连接所有点,则输出oh!
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #include <math.h> 5 #define MAXN 205 6 #define inf 1000000000 7 double Map[MAXN][MAXN]; 8 void Crate_MAP(int N) 9 { 10 int i,j; 11 for(i=1;i<=N;i++) 12 for(j=1;j<=N;j++) 13 { 14 if(i==j) 15 Map[i][j]=0; 16 else 17 Map[i][j]=inf; 18 } 19 } 20 double Prim(int N,int* pre) 21 { 22 double min[MAXN],ret=0; 23 int v[MAXN],i,j,k; 24 for (i=1;i<=N;i++) 25 min[i]=inf,v[i]=0,pre[i]=-1; 26 for (min[j=1]=0;j<=N;j++) 27 { 28 for (k=-1,i=1;i<=N;i++) 29 if (!v[i]&&(k==-1||min[i]<min[k])) 30 k=i; 31 for (v[k]=1,ret+=min[k],i=1;i<=N;i++) 32 if (!v[i]&&Map[k][i]<min[i]) 33 min[i]=Map[pre[i]=k][i]; 34 } 35 return ret; 36 } 37 double Dic(double a,double b) 38 { 39 double sum=a*a+b*b; 40 if(sum>0)return sum; 41 else return (-sum); 42 } 43 int main() 44 { 45 double a[105],b[105],sum; 46 int T,N,i,j,c,pre[205],sign; 47 scanf("%d",&T); 48 while(T--) 49 { 50 sign=0; 51 scanf("%d",&N); 52 Crate_MAP(N); 53 memset(pre,0,sizeof(pre)); 54 for(i=1;i<=N;i++) 55 scanf("%lf%lf",&a[i],&b[i]); 56 for(i=1;i<=N;i++) 57 for(j=i+1;j<=N;j++) 58 { 59 sum=sqrt(Dic(a[i]-a[j],b[i]-b[j])); 60 if(sum<10||sum>1000)continue; 61 if(Map[i][j]==inf)sign++; 62 if(Map[i][j]>sum) 63 { 64 Map[i][j]=sum; 65 Map[j][i]=sum; 66 } 67 } 68 if(sign>=N-1) 69 printf("%.1lf\n",100*Prim(N,pre)); 70 else 71 printf("oh!\n"); 72 } 73 return 0; 74 }
修改:2015.6.8(Prim)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 #include <stdio.h> 3 #include <string.h> 4 #include <math.h> 5 #define MAX 1100 6 using namespace std; 7 struct node 8 { 9 double x,y; 10 }POINT[MAX]; 11 int Point[MAX];/*标记点i的状态*/ 12 void Cread(int N) 13 { 14 for(int i=0;i<=N;i++)Point[i]=1; 15 } 16 17 double DIC(double x,double y) 18 { 19 return sqrt(x*x+y*y); 20 } 21 double Prim(int N)/*如果可构成最小生成树,返回最小权值*/ 22 { /*否则返回-1,表示无法构成最小生成树,O(N^3)*/ 23 int i,j,k,ii,jj; 24 double Sum_Min=0,MIN,TMD; 25 int P[MAX]={0};/*记录点集合*/ 26 double PX,PY; 27 P[1]=1;Point[1]=0; 28 for(k=2;k<=N;k++) 29 { 30 for(i=1,MIN=1000010;i<k;i++) 31 { 32 for(j=1;j<=N;j++) 33 { 34 if(Point[j]) 35 { 36 PX=POINT[P[i]].x-POINT[j].x; 37 PY=POINT[P[i]].y-POINT[j].y; 38 TMD=DIC(PX,PY); 39 if(TMD>=10&&TMD<=1000) 40 { 41 if(TMD<MIN) 42 { 43 ii=P[i];jj=j; 44 MIN=TMD; 45 P[k]=j; 46 } 47 } 48 } 49 } 50 } 51 if(MIN==1000010)break; 52 Sum_Min+=MIN; 53 Point[P[k]]=0; 54 } 55 if(k==N+1)return Sum_Min; 56 else return -1; 57 } 58 int main() 59 { 60 int i,j,k,N,M,T; 61 scanf("%d",&T); 62 while(T--) 63 { 64 scanf("%d",&N); 65 Cread(N); 66 double a,b; 67 for(i=1;i<=N;i++) 68 { 69 scanf("%lf%lf",&a,&b); 70 POINT[i].x=a; 71 POINT[i].y=b; 72 } 73 double Min=Prim(N); 74 if(Min==-1)printf("oh!\n"); 75 else printf("%.1lf\n",100*Min); 76 } 77 return 0; 78 }
修改:2015.7.27(快排+并查集)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 #include <stdio.h> 3 #include <math.h> 4 #include <algorithm> 5 #define MAX 1008 6 using namespace std; 7 struct poin 8 { 9 int x; 10 int y; 11 double s; 12 }Dic[100100]; 13 14 int cmp(poin a,poin b) 15 { 16 return a.s<b.s; 17 } 18 int ID[MAX]; 19 int Sign; 20 double X[MAX]; 21 double Y[MAX]; 22 double Map[MAX][MAX]; 23 double DIC(double x,double y) 24 { 25 return sqrt(x*x+y*y); 26 } 27 void Cread(int N) 28 { 29 int i,j; 30 Sign=0; 31 for(i=0;i<=N;i++) 32 { 33 ID[i]=i; 34 for(j=0;j<=N;j++) 35 Map[i][j]=MAX; 36 } 37 } 38 39 int Find(int x) 40 { 41 int TMD; 42 if(x==ID[x])return x; 43 else ID[x]=Find(ID[x]); 44 return ID[x]; 45 } 46 47 void Update(int a,int b) 48 { 49 int A,B; 50 A=Find(a);B=Find(b); 51 if(A!=B)ID[A]=B; 52 else Sign++; 53 } 54 int main() 55 { 56 int T,N,i,j,k,A,B,C,t=1; 57 double X[MAX],Y[MAX],c; 58 scanf("%d",&T); 59 while(T--) 60 { 61 scanf("%d",&N); 62 Cread(N); 63 for(i=0;i<N;i++) 64 { 65 scanf(" %lf %lf",&X[i],&Y[i]); 66 } 67 for(i=0;i<N;i++) 68 { 69 for(j=0;j<N;j++) 70 { 71 Dic[i*N+j].x=i; 72 Dic[i*N+j].y=j; 73 if(i==j){Dic[i*N+j].s=MAX;} 74 c=DIC(X[i]-X[j],Y[i]-Y[j]); 75 if(c<10||c>1000)c=MAX; 76 Dic[i*N+j].s=c; 77 } 78 } 79 sort(Dic,Dic+N*N,cmp); 80 double Sum=0; 81 int Sign=0; 82 for(k=0;k<N*N;k++) 83 { 84 if(fabs(Dic[k].s-MAX)<=0.00001){Sign=0;break;} 85 else 86 { 87 A=Find(Dic[k].x);B=Find(Dic[k].y); 88 if(A!=B) 89 { 90 ID[A]=B; 91 Sum+=Dic[k].s; 92 Sign++; 93 } 94 } 95 if(Sign==N-1){printf("%.1lf\n",Sum*100);break;} 96 } 97 if(Sign!=N-1)printf("oh!\n"); 98 } 99 return 0; 100 }
转载请备注:
**************************************
* 作者: Wurq
* 博客: https://www.cnblogs.com/Wurq/
* Gitee: https://gitee.com/wurq
**************************************
**************************************
* 作者: Wurq
* 博客: https://www.cnblogs.com/Wurq/
* Gitee: https://gitee.com/wurq
**************************************