zoukankan      html  css  js  c++  java
  • AOJ

    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
    ",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
    ",kruskal());
    93     }
    94     return 0;
    95 }
  • 相关阅读:
    针对性博文
    spring事务
    Redis_主从模式_哨兵模式_Cluster集群模式
    Redis AOF、RDB持久化
    Redis 高可用分布式集群
    Redis 基础
    Oracle优化学习
    Mysql:索引实战
    Mysql:性能优化
    js 二维数组定义
  • 原文地址:https://www.cnblogs.com/nowandforever/p/4512996.html
Copyright © 2011-2022 走看看