HDOJ--1875--畅通工程再续

来源:互联网 发布:python index 编辑:程序博客网 时间:2024/05/16 17:02
欢迎参加——每周六晚的BestCoder(有米!)

畅通工程再续

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 19576    Accepted Submission(s): 6129


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
2210 1020 2031 12 21000 1000
 

Sample Output
1414.2oh!
 

思路:这道题其实还是最小生成树问题,比较笨,只学了克鲁斯卡尔算法,所以就只用边了,关键就在于构造边,并且构造的边要满足题意。
ac代码:
#include<stdio.h>#include<algorithm>#include<math.h>using namespace std;struct loc{int x,y,num;}a[1010];struct node{int b,e;double l;}edge[100*100]; int per[100*100],n;bool cmp(node c,node d){return c.l<d.l;}void init(){for(int i=1;i<=n;i++)per[i]=i;}int find(int x){int r=x;while(r!=per[r]){r=per[r];}int i=x,j;while(i!=r){j=per[i];per[i]=r;i=j;} return r;} int join(int a,int b){int fa=find(a);int fb=find(b);if(fa!=fb){per[fa]=fb;return 1;}elsereturn 0;}double fun(int x1,int y1,int x2,int y2){double l=sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));return l;}int main(){int T;scanf("%d",&T);while(T--){int i,j,k=0,cnt=0; //点的数量.scanf("%d",&n);init();for(i=1;i<=n;i++){scanf("%d%d",&a[i].x,&a[i].y);a[i].num=i;}for(i=1;i<=n;i++)for(j=i+1;j<=n;j++){double l=fun(a[i].x,a[i].y,a[j].x,a[j].y);if(l>=10&&l<=1000){edge[++k].b=a[i].num;edge[k].e=a[j].num;edge[k].l=l;}}sort(edge+1,edge+k+1,cmp);double  sum=0;for(i=1;i<=k;i++){if(join(edge[i].b,edge[i].e))sum+=edge[i].l;}for(i=1;i<=n;i++)if(per[i]==i)cnt++;if(cnt!=1)//用来判断有几个集合,有一个集合的话就刚好畅通了。 printf("oh!\n");else{sum*=100;printf("%.1lf\n",sum);}}return 0;}
第二次做了,这次用prime算法来做,prime算法对于比较稠密的图确实有很大的优势。
ac代码:
#include<stdio.h>#include<string.h>#include<math.h>#define INF 0x3f3f3f3fint c,vis[101];double sum,dis[101],map[101][101],flag;struct node{int x,y,num;}eg[101];double fun(int x1,int y1,int x2,int y2){double l=sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));return l;}void prime(){int i;sum=0;for(i=1;i<=c;i++)dis[i]=map[1][i];vis[1]=1;for(i=1;i<c;i++){int j,k;double temp=INF;for(j=1;j<=c;j++)if(vis[j]==0&&temp>dis[j])temp=dis[k=j];if(temp==INF){flag=1;break;}vis[k]=1;sum+=temp;for(j=1;j<=c;j++)if(vis[j]==0&&dis[j]>map[k][j])dis[j]=map[k][j];}}int main(){int t;scanf("%d",&t);while(t--){memset(vis,0,sizeof(vis));scanf("%d",&c);for(int i=1;i<=c;i++){scanf("%d%d",&eg[i].x,&eg[i].y);eg[i].num=i;}for(int i=1;i<=c;i++)for(int j=i+1;j<=c;j++){double l=fun(eg[i].x,eg[i].y,eg[j].x,eg[j].y);if(l>=10&&l<=1000)map[i][j]=map[j][i]=l;elsemap[i][j]=map[j][i]=INF;}prime();if(flag)printf("oh!\n");elseprintf("%.1lf\n",sum*100.0);}return 0;}



0 0
原创粉丝点击