相信大家都听说一个“百岛湖”的地方吧,百岛湖的居民生活在不同的小岛中,当他们想去其他的小岛时都要通过划小船来实现。现在政府决定大力发展百岛湖,发展首先要解决的问题当然是交通问题,政府决定实现百岛湖的全畅通!经过考察小组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
Sample Output
1414.2 oh!
咳,wr了10多次,真是服了,原来是sum没有初始化为0,难受啊;
这个题是最小生成树,但是与模板有些不同。
需要以每个点为起点,把其后的遍历一遍,简单来说,就是把每两个点放在一个结构体里,注意,这里存的是两个点的序号,以及两点间的距离。然后进行find,join的操作。
看这个题,给的是坐标,不像之前做的初级模板题,他们是两个独立点,好弄。但这里我们不看坐标了,需要存的是序号,因为一个x,y就是一个点。其他的按套路来就可以了。
1 #include<iostream> 2 #include<cmath> 3 #include<algorithm> 4 using namespace std; 5 int pr[1205]; 6 int n; 7 int x[1205],y[1205]; 8 struct node 9 { 10 int x,y; 11 double d; 12 }s[10010]; 13 bool cmp(node a,node b) 14 { 15 return a.d<b.d; 16 } 17 int find(int x) 18 { 19 if(x!=pr[x]) 20 return pr[x]=find(pr[x]); 21 return x; 22 } 23 int join(int a,int b) //判断成环 24 { 25 int f1=find(a); 26 int f2=find(b); 27 if(f1!=f2) 28 { 29 pr[f1]=f2; 30 return 1; 31 } 32 return 0; 33 } 34 int main() 35 { 36 int t; 37 cin>>t; 38 while(t--) 39 { 40 int n; 41 cin>>n; 42 double d,sum=0; 43 int tot=0; 44 int ans=0; //两两相连,一共可建ans个桥。 45 for(int i=0;i<=n;i++) 46 pr[i]=i; 47 for(int i=0;i<n;i++) 48 cin>>x[i]>>y[i]; 49 for(int i=0;i<n-1;i++) 50 for(int j=i+1;j<n;j++) 51 { 52 d=sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j])); 53 if(d>=10&&d<=1000) 54 { 55 s[tot].x=i; //记录编号。 56 s[tot].y=j; 57 s[tot].d=d; 58 tot++; 59 } 60 } 61 sort(s,s+tot,cmp); 62 for(int i=0;i<tot;i++) 63 { 64 if(join(s[i].x,s[i].y)) 65 { 66 sum+=s[i].d; 67 ans++; //已连桥数。 68 } 69 } 70 if(ans==n-1) //此为一棵树。 71 printf("%.1lf ",sum*100); 72 else 73 printf("oh! "); 74 } 75 return 0; 76 }