hdu 1875 畅通工程再续

一般来说能用prim算法解决的用kruscal算法也能解决问题,所以为了锻炼自己,能用的都用两种方法解决;

1.prim

用prim也是简单的套模板,就是多了一步计算两点间距离,将距离不满足题意的两点的距离设为无穷大.没有什么难度;

 1 #include <iostream>
 2 #include <string.h>
 3 #include <stdio.h>
 4 #include <math.h>
 5 using namespace std;
 6 const double INF=0x3f3f3f3f*1.0;
 7 struct node
 8 {
 9     int x;
10     int y;
11 };
12 
13 double d[105][105];
14 int c;//岛屿个数
15 void prim()
16 {
17     double sum=0,lowcast[105]={0};
18     int count=1;
19     for(int i=0;i<c;i++)
20     {
21         lowcast[i] = d[0][i];
22     }
23     for(int i=0;i<c-1;i++)
24     {
25         double min = INF;
26         int k = 105;
27         for(int j=0;j<c;j++)
28             if(min>lowcast[j]&&lowcast[j])
29             {
30                 min = lowcast[j];
31                 k = j;
32             }
33             if(k!=105)
34             {
35                 sum+=lowcast[k];
36                 lowcast[k]=0;
37                 count++;
38             }
39             for(int j=0;j<c;j++)
40                 if(d[j][k]<lowcast[j])
41                 {
42                     lowcast[j] = d[j][k];
43                 }
44     }
45     if(count==c)
46         printf("%.1lf\n",sum*100);
47     else
48         printf("oh!\n");
49 }
50 int main()
51 {
52 
53     int t;
54     cin>>t;
55     while(t--)
56     {
57         node n[105];
58         cin>>c;
59         for(int i=0;i<c;i++)
60             cin>>n[i].x>>n[i].y;
61         for(int i=0;i<c;i++)
62             for(int j=0;j<c;j++)
63             {
64                 if(i==j)
65                 {        
66                     d[i][j]=0;
67                     continue;
68                 }
69 
70                 int x1=n[i].x, x2=n[j].x;
71                 int y1=n[i].y, y2=n[j].y;
72                 double dist=sqrt(1.0*(x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
73                 if(dist<10.0||dist>1000.0)//无法建桥
74                     d[j][i]=d[i][j]=INF;
75                 else
76                     d[j][i]=d[i][j]=dist;
77             }
78             prim();
79     }
80     return 0;
81 }
查看代码

2.kruscal

这题用kruscal也是简单的模板,与prim一样,都需要做一个两点间距离的预处理.

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <string.h>
 4 #include <algorithm>
 5 using namespace std;
 6 #define maxn 105 
 7 #define  INF 0x3f3f3f3f*1.0
 8 int father[maxn];
 9 int n,T;
10 struct point{
11     int x,y;
12 }coor[maxn];
13 struct node{
14     int u , v;
15     double w;
16 }edge[maxn*60];
17 void init()
18 {
19     for(int i = 0 ;i <= n ;i++)
20         father[i] = i;
21 }
22 int find(int x)
23 {
24     if(father[x]==x)
25         return x;
26     return father[x]=find(father[x]);
27 }
28 void unite(int x,int y)
29 {
30     int fx = find(x) , fy = find(y);
31     if(fx == fy)
32         return ;
33     father[fy] = fx;
34 }
35 bool cmp(node a , node b)
36 {
37     return a.w < b.w;
38 }
39 double kruscal(int t)
40 {
41     int count = 0;
42     double res = 0;
43     int u,v;
44     for(int i = 0 ;i < t; i++)
45     {
46         u = edge[i].u;
47         v = edge[i].v;
48         //if(count == n) 没加 327MS,加了514MS; 
49             //return res;
50         if(find(u)!=find(v))
51         {
52             unite(u,v);
53             count++;
54             res += edge[i].w;
55 
56         }
57 
58     }
59     return res;
60 }
61 int main()
62 {
63     //freopen("hdu 1233.txt","r",stdin);
64     double dis;
65     int t, x,y ;
66     scanf("%d",&T);
67     while(T--)
68     {
69         scanf("%d",&n);
70         init();
71         t= 0;
72         for(int i = 0 ;i < n ; i++)
73         {
74             scanf("%d %d",&x,&y);
75             coor[i].x = x;
76             coor[i].y = y;
77             for(int j = 0 ; j <=i ;j++)
78             {
79                 dis = sqrt((double)(coor[i].x - coor[j].x)*(coor[i].x-coor[j].x)+(double)(coor[i].y - coor[j].y)*(coor[i].y-coor[j].y));
80                  if(dis < 10 || dis > 1000)
81                      continue;
82                  edge[t].u = i;
83                  edge[t].v = j;
84                  edge[t++].w = dis;
85                 // cout<<dis<<" ";
86             }
87         }
88         sort(edge,edge+t,cmp);
89         double ans = kruscal(t);
90         if(ans > 0){
91             printf("%.1lf\n",ans*100);
92         }else
93         {
94             printf("oh!\n");
95         }
96     }
97     return 0;
98 }
View Code

 

转载于:https://www.cnblogs.com/xiaoniuniu/p/4392483.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值