http://acm.hdu.edu.cn/showproblem.php?pid=1875
Problem Description
相信大家都听说一个“百岛湖”的地方吧,百岛湖的居民生活在不同的小岛中,当他们想去其他的小岛时都要通过划小船来实现。现在政府决定大力发展百岛湖,发展首先要解决的问题当然是交通问题,政府决定实现百岛湖的全畅通!经过考察小组RPRush对百岛湖的情况充分了解后,决定在符合条件的小岛间建上桥,所谓符合条件,就是2个小岛之间的距离不能小于10米,也不能大于1000米。当然,为了节省资金,只要求实现任意2个小岛之间有路通即可。其中桥的价格为 100元/米。
Input
输入包括多组数据。输入首先包括一个整数T(T <= 200),代表有T组数据。
每组数据首先是一个整数C(C <= 100),代表小岛的个数,接下来是C组坐标,代表每个小岛的坐标,这些坐标都是 0 <= x, y <= 1000的整数。
每组数据首先是一个整数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!
1 #include <stdio.h> 2 #include <string.h> 3 #include <iostream> 4 #include <string> 5 #include <math.h> 6 #include <algorithm> 7 #include <vector> 8 #include <stack> 9 #include <queue> 10 #include <set> 11 #include <map> 12 #include <sstream> 13 const int INF=0x3f3f3f3f; 14 typedef long long LL; 15 const int mod=1e9+7; 16 //const double PI=acos(-1); 17 #define Bug cout<<"---------------------"<<endl 18 const int maxn=1e5+10; 19 using namespace std; 20 21 struct edge_node 22 { 23 int to; 24 double val; 25 int next; 26 }Edge[maxn]; 27 int Head[110]; 28 int tot; 29 double MST;//存放最小生成树权值和 30 31 struct node 32 { 33 int x; 34 int y; 35 }PT[110];//点信息 36 37 void Add_Edge(int u,int v,double w) 38 { 39 Edge[tot].to=v; 40 Edge[tot].val=w; 41 Edge[tot].next=Head[u]; 42 Head[u]=tot++; 43 } 44 45 double lowval[110]; 46 int pre[110];//记录每个点的双亲是谁 47 48 double Prim(int n,int st)//n为顶点的个数,st为最小生成树的开始顶点 49 { 50 double sum=0; 51 fill(lowval,lowval+n,INF);//根据编号从0或是1开始,改+1 52 memset(pre,-1,sizeof(pre)); 53 lowval[st]=-1; 54 pre[st]=-1; 55 int num=0;//num是目前可以添加到最小生成树中的点的数量 56 for(int i=Head[st];i!=-1;i=Edge[i].next) 57 { 58 int v=Edge[i].to; 59 double w=Edge[i].val; 60 lowval[v]=min(lowval[v],w); 61 pre[v]=st; 62 num++; 63 } 64 while(num) 65 { 66 double MIN=INF; 67 int k; 68 for(int i=0;i<n;i++)//根据编号从0或是1开始,改i从0--n-1和1--n 69 { 70 if(lowval[i]!=-1&&lowval[i]<MIN) 71 { 72 MIN=lowval[i]; 73 k=i; 74 } 75 } 76 sum+=MIN; 77 lowval[k]=-1; 78 num--; 79 for(int j=Head[k];j!=-1;j=Edge[j].next) 80 { 81 int v=Edge[j].to; 82 double w=Edge[j].val; 83 if(w<lowval[v]) 84 { 85 if(lowval[v]==INF) 86 num++; 87 lowval[v]=w; 88 pre[v]=k; 89 } 90 } 91 } 92 for(int i=0;i<n;i++)//判断每个点的pre,看是否有双亲 93 { 94 if(i!=st&&pre[i]==-1) 95 return INF; 96 } 97 return sum; 98 } 99 100 int main() 101 { 102 int T; 103 scanf("%d",&T); 104 while(T--) 105 { 106 int n; 107 scanf("%d",&n); 108 memset(Head,-1,sizeof(Head)); 109 tot=0; 110 for(int i=0;i<n;i++) 111 scanf("%d %d",&PT[i].x,&PT[i].y); 112 for(int i=0;i<n;i++) 113 { 114 for(int j=i+1;j<n;j++) 115 { 116 int x=PT[i].x-PT[j].x; 117 int y=PT[i].y-PT[j].y; 118 double val=sqrt(x*x+y*y); 119 if(val>=10&&val<=1000) 120 { 121 Add_Edge(i,j,val); 122 Add_Edge(j,i,val); 123 } 124 } 125 } 126 MST=Prim(n,0); 127 if(MST==INF) 128 printf("oh! "); 129 else 130 printf("%.1f ",MST*100); 131 } 132 return 0; 133 }