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 }
  • 相关阅读:
    软测试-计算机组成原理、系统和网络安全机构
    POJ 2044 Weather Forecast
    Cocos2d-x 3.x 头像选择,本地相册图片+图片编辑(Android、IOS双平台)
    Spring-----1、Spring一个简短的引论
    捕android程序崩溃日志
    java 正则表达式例子, 查找字符串
    java中Pattern.compile函数的相关解释
    java JdbcTemplate源码
    eclipse 常用快捷键整理
    java 正则表达式去除标点符号
  • 原文地址:https://www.cnblogs.com/nowandforever/p/4512996.html
Copyright © 2011-2022 走看看