zoukankan      html  css  js  c++  java
  • AOJ2224(最小(大)生成树)

    题目描述:

      有很多猫被困在一个图中,这些图由若干点组成,然后给了若干连线,把这个图分为了几个区域,请你求出把这个图消去若干条边,最后使这个图没有封闭区域,请问最小的花费是多少(花费等于边长总和)

    思路:

      一开始并没有头绪,后来发现把一个图变成一个没有封闭区域的图的最小花费=图的总权值-最大生成树的花费

      然后就交了一发MST就过了

      代码:

     1 #include<cstdio>
     2 #include<iostream>
     3 #include <algorithm>
     4 #include <cmath>
     5 using namespace std;
     6 const int maxn=1e4+5;
     7 const int maxm=1e8+5;
     8 int m,n,par[maxn],cnt;
     9 struct edge
    10 {
    11     int fro,to;
    12     double v;
    13 }E[maxm];
    14 struct node
    15 {
    16     int x,y;
    17 }poi[maxn];
    18 bool cmp(edge a,edge b)
    19 {
    20     return a.v>b.v;
    21 }
    22 double len(node a,node b)
    23 {
    24     int x=a.x-b.x,y=a.y-b.y;
    25     return sqrt(x*x+y*y);
    26 }
    27 void add(int a,int b,double c)
    28 {
    29     E[cnt].fro=a;
    30     E[cnt].to=b;
    31     E[cnt++].v=c;
    32 }
    33 int find(int x)
    34 {
    35     int r=x;
    36     while(r!=par[r]) r=par[r];
    37     int i=x,k;
    38     while(i!=r)
    39     {
    40         k=par[i];
    41         par[i]=r;
    42         i=k;
    43     }
    44     return r;
    45 }
    46 void unio(int x,int y)
    47 {
    48     x=find(x),y=find(y);
    49     par[x]=y;
    50 }
    51 double Kruskal()
    52 {
    53     double ans=0;
    54     for(int i=1;i<=maxn;i++) par[i]=i;
    55     sort(E,E+cnt,cmp);
    56     for(int i=0;i<cnt;i++)
    57     {
    58         edge e=E[i];
    59         if(find(e.fro)!=find(e.to))
    60         {
    61             ans+=e.v;
    62             unio(e.fro,e.to);
    63         }
    64     }
    65     return ans;
    66 }
    67 int main()
    68 {
    69     double sum;
    70     scanf("%d%d",&n,&m);
    71     for(int i=1;i<=n;i++)
    72     {
    73         int x,y;
    74         scanf("%d%d",&x,&y);
    75         poi[i].x=x,poi[i].y=y;
    76     }
    77     for(int i=1;i<=m;i++)
    78     {
    79         int a,b;
    80         scanf("%d%d",&a,&b);
    81         double c=len(poi[a],poi[b]);
    82         add(a,b,c);
    83         sum+=c;
    84     }
    85     double ans=sum-Kruskal();
    86     printf("%.3lf
    ",ans );
    87 }
    View Code
  • 相关阅读:
    LightOJ 1132 Summing up Powers(矩阵快速幂)
    hdu 3804 Query on a tree (树链剖分+线段树)
    LightOJ 1052 String Growth && uva 12045 Fun with Strings (矩阵快速幂)
    uva 12304 2D Geometry 110 in 1! (Geometry)
    LA 3263 That Nice Euler Circuit (2D Geometry)
    2013 SCAUCPC Summary
    poj 3321 Apple Tree (Binary Index Tree)
    uva 11796 Dog Distance (几何+模拟)
    uva 11178 Morley's Theorem (2D Geometry)
    动手动脑
  • 原文地址:https://www.cnblogs.com/codeoosacm/p/10115703.html
Copyright © 2011-2022 走看看