码迷,mamicode.com
首页 > 其他好文 > 详细

AOJ - 2224 Save your cat(最小生成树)

时间:2015-05-18 22:49:35      阅读:164      评论:0      收藏:0      [点我收藏+]

标签:

http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=45524

NY在自己的花园里养了很多猫。有一天,一个巫婆在N个点设置了魔法,然后有M条关系,每一条在两个点之间有栅栏。

NY需要损坏这些栅栏但是需要栅栏长度这么多神奇的水,因为这种水很昂贵所以希望水用的越少越好。输出最少花费。

输入N,M表示N个点,接下来N行每行一个点的坐标,接下来M行每行两个数表示x,y之间有栅栏相连。

没有栅栏会交叉,每个圈都至少有一只猫。

题目意思就是如果图产生了圈就要把一些边去掉,破坏这个圈,问需要破坏的边的最小长度。

那么每次并查集的时候只要判断在同一个连通分量那么就需要破坏掉这条边,累加即可。因为不会有重边,所以

按边的权值从大到小或者从小到大都可以。

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cmath>
 4 #include <algorithm>
 5 using namespace std;
 6 
 7 struct node
 8 {
 9     int x,y,id;
10 };
11 struct edge
12 {
13     int u,v;
14     double cost;
15     edge() {}
16     edge(int x,int y,double z)
17     {
18         u=x;
19         v=y;
20         cost=z;
21     }
22     bool operator <(const edge& a) const
23     {
24         return cost>a.cost;
25     }
26 };
27 
28 edge es[50010];
29 int par[10010];
30 node p[10010];
31 int n,m;
32 void init()
33 {
34     for(int i=1;i<=n;i++) par[i]=i;
35 }
36 
37 int find(int x)
38 {
39     return x==par[x]?x:par[x]=find(par[x]);
40 }
41 
42 void unite(int x,int y)
43 {
44     x=find(x);
45     y=find(y);
46     if(x!=y) par[x]=y;
47 }
48 
49 double dis(int a,int b)
50 {
51     return sqrt(1.0*(p[a].x-p[b].x)*(p[a].x-p[b].x)+1.0*(p[a].y-p[b].y)*(p[a].y-p[b].y));
52 }
53 
54 double kruskal()
55 {
56     sort(es,es+m);
57     //for(int i=0;i<m;i++) printf("%d %d %lf\n",es[i].u,es[i].v,es[i].cost);
58     double s=0;
59     for(int i=0;i<m;i++)
60     {
61         edge e=es[i];
62         if(find(e.u)!=find(e.v))
63         {
64             unite(e.u,e.v);
65         }
66         else
67         {
68             s+=e.cost;
69         }
70     }
71     return s;
72 }
73 int main()
74 {
75     //freopen("a.txt","r",stdin);
76     int a,b;
77     double c,sum;
78     while(~scanf("%d%d",&n,&m))
79     {
80         init();
81         sum=0;
82         for(int i=1;i<=n;i++)
83         {
84             scanf("%d%d",&p[i].x,&p[i].y);
85         }
86         for(int i=0;i<m;i++)
87         {
88             scanf("%d%d",&a,&b);
89             c=dis(a,b);
90             es[i]=edge(a,b,c);
91         }
92         printf("%.3lf\n",kruskal());
93     }
94     return 0;
95 }

 

AOJ - 2224 Save your cat(最小生成树)

标签:

原文地址:http://www.cnblogs.com/nowandforever/p/4512996.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!