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 }
  • 相关阅读:
    dubbo入门(一)
    java中文件操作《一》
    Unity 游戏框架搭建 2019 (七) 自定义快捷键
    凉鞋:我所理解的框架 【Unity 游戏框架搭建】
    Unity 游戏框架搭建 2019 (六) MenuItem 复用
    Unity 游戏框架搭建 2019 (五) 打开所在文件夹
    Unity 游戏框架搭建 2019 (四) 导出 UnityPackage
    Unity 游戏框架搭建 2019 (三) 生成文件名到剪切板
    Unity 游戏框架搭建 2019 (二) 文本复制到剪切板
    Unity 游戏框架搭建 2019 (一) 简介与第一个示例文件名的生成
  • 原文地址:https://www.cnblogs.com/nowandforever/p/4512996.html
Copyright © 2011-2022 走看看