HDU - 1875_暢通工程再續
阿新 • • 發佈:2018-11-03
暢通工程再續
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
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
Sample Output
1414.2
oh!
題解:用kruskal求最小生成樹,注意判斷邊權,然後在並茶几那裡出bug了,wa了好幾發。
#include <algorithm> #include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <cmath> using namespace std; const int maxn = 1050; struct point { int x,y; }p[105]; struct edge { int v,u; double w; }s[10050]; int num,head[maxn],n; void add(int u,int v,double w) { // cout<<u<<' '<<v<<' '<<w<<endl; s[num].u = u; s[num].v = v; s[num].w = w; num++; } double dis(point a,point b) { return sqrt(1.0*(a.x-b.x)*(a.x-b.x)+1.0*(a.y-b.y)*(a.y-b.y)); } int Find(int x) { return x==head[x]?x:head[x] = Find(head[x]); } double kruskal() { double w,sum = 0; int i,v,u,ans = 0; for(i=0;i<num;i++) { u = s[i].u; v = s[i].v; w = s[i].w; //cout<<"WTF"<<endl; int a = Find(u); int b = Find(v); if(a!=b&&w>=10&&w<=1000) { //cout<<w<<endl; head[b] = a; sum += w; } } for(i=0;i<n;i++) { if(head[i]==i) ans ++; } if(ans==1) return sum; return -1; } void init(int n) { for(int i=0;i<n;i++) head[i] = i; } bool cmp(edge a,edge b) { return a.w<b.w; } int main() { int i,t,j; scanf("%d",&t); while(t--) { num = 0; scanf("%d",&n); init(n); for(i=0;i<n;i++) { scanf("%d%d",&p[i].x,&p[i].y); for(j=0;j<i;j++) { add(i,j,dis(p[i],p[j])); } } if(n==1||n==0) { printf("0\n"); continue; } sort(s,s+num,cmp); double a = kruskal(); if(a==-1) printf("oh!\n"); else printf("%.1f\n",a*100); } return 0; }