畅通工程再续
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 19501 Accepted Submission(s): 6112
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!代码:Kruskal算法:#include<stdio.h> #include<algorithm> #include<math.h> using namespace std; int n; int per[110]; int x[110],y[110]; struct record { int s,e; double w; }num[10000]; bool cmp(record a,record b) { return a.w<b.w; } int init() { for(int i=1;i<=n;i++) { per[i]=i; } } int find(int x) { int r; r=x; while(r!=per[r]) { r=per[r]; } per[x]=r; return r; } int join(int x,int y) { int fx=find(x); int fy=find(y); if(fx!=fy) { per[fx]=fy; return true; } return false; } int main() { int t,k,f,i,j; scanf("%d",&t); while(t--) { k=0;f=1; double sum=0,d; scanf("%d",&n); for(i=1;i<=n;i++) { scanf("%d%d",&x[i],&y[i]); } init(); for(i=1;i<=n;i++) { for(j=i+1;j<=n;j++) { d=sqrt((x[j]-x[i])*(x[j]-x[i])+(y[j]-y[i])*(y[j]-y[i])); if(d>=10&&d<=1000) { num[k].s=i; num[k].e=j; num[k].w=d; k++; } } } sort(num,num+k,cmp); for(i=0;i<k;i++) { if(join(num[i].s,num[i].e)) { sum+=num[i].w; f++; } } if(f==n) { printf("%.1lf\n",sum*100); } else { printf("oh!\n"); } } return 0; }
Prim算法:#include<stdio.h> #include<math.h> #include<string.h> #define INF 0x3f3f3f int vis[110]; int x[110],y[110]; double low[110],map[110][110]; int n; void prim() { int next,i,j; double sum,min; memset(vis,0,sizeof(vis)); for(i=1;i<=n;i++) { low[i]=map[1][i]; } vis[1]=1; for(i=2;i<=n;i++) { min=INF; for(j=1;j<=n;j++) { if(!vis[j]&&min>low[j]) { min=low[j]; next=j; } } if(min==INF) { printf("oh!\n"); return ; } sum+=min; vis[next]=1; for(j=1;j<=n;j++) { if(!vis[j]&&low[j]>map[next][j]) { low[j]=map[next][j]; } } } printf("%.1lf\n",sum*100); } int main() { int t,i,j; double d; scanf("%d",&t); while(t--) { scanf("%d",&n); for(i=1;i<=n;i++) { scanf("%d%d",&x[i],&y[i]); } for(i=1;i<=n;i++) { for(j=1;j<=n;j++) { d=sqrt((x[j]-x[i])*(x[j]-x[i])+(y[j]-y[i])*(y[j]-y[i])); if(d>=10&&d<=1000) { map[i][j]=map[j][i]=d; } else map[i][j]=map[j][i]=INF; } } prim(); } return 0; }