Aizu-2224Save your cats并查集+最小生成树

Save your cats

题意:存在n个点,有m条边( input中读入的是 边的端点,要先转化为边的长度 ),做一个最小生成树,使得要去除的边的长度总和最小;

思路:利用并查集和求最小生成树的方法,注意这里的排序要从大到小排,这样最后建树的消耗最大,反过来去除的最小;

当然题意不是这么直白,感觉以后看到要做一个不成环的图时,要想到最小生成树;

下面是ac代码:

#include <cstdio>
#include <iostream>
#include <cstring>
#include <string>
#include <algorithm>
#include <cmath>
const int maxn =10007;
const int mx   =2e6+7;
using namespace std;
int n,m,fa[maxn];
struct node {
    int from;
    int to;
    double r;
}a[mx];
struct nn{
    int x,y;
}p[maxn];

bool cmp(node a,node b)
{
    return a.r>b.r;                    //这里的判断用大于,使得sort从大到小排列
}
void init(){
    for(int i=1;i<=n;i++)
        fa[i] = i;
    memset(a,0,sizeof(a));
    memset(p,0,sizeof(p));
}
int find(int x)
{
    if(fa[x]==x)return x;
    else return fa[x] = find (fa[x]);
}
bool uni(int x,int y)
{
    int px = find(x);
    int py = find (y);
    if(px==py)return false;
    fa[px] = py;
    return true;
}
int main(){
    scanf("%d%d",&n,&m);
    init();
    for(int i=1;i<=n;i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        p[i].x=x;
        p[i].y=y;
    }
    double sum = 0,res=0;
    for(int i=1;i<=m;i++)
    {
        int u,v;
        scanf("%d%d",&u,&v);
        double tmp = sqrt((p[u].x-p[v].x)*(p[u].x-p[v].x)+(p[u].y-p[v].y)*(p[u].y-p[v].y));
        a[i].from=u;
        a[i].to=v;
        a[i].r = tmp;
        sum+=tmp;
    }
    sort(a+1,a+1+m,cmp);
    for(int i=1;i<=m;i++)
    {
        int u = a[i].from;
        int v = a[i].to;
        if(uni(u,v))res+=a[i].r;
    }
    printf("%.3lf\n",sum-res);
    return 0;
}

原文地址:https://www.cnblogs.com/ckxkexing/p/8448501.html

时间: 2024-11-10 15:40:55

Aizu-2224Save your cats并查集+最小生成树的相关文章

ACM: 继续畅通工程-并查集-最小生成树-解题报告

继续畅通工程 Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Submit Status Description 省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可).现得到城镇道路统计表,表中列出了任意两城镇间修建道路的费用,以及该道路是否已经修通的状态.现请你编写程序,计算出全省畅通需要的最低成本. Input 测试输入包含若干测试用例

Kruskal算法(贪心+并查集=最小生成树)

http://www.51nod.com/ Kruskal算法的高效实现需要一种称作并查集的结构.我们在这里不介绍并查集,只介绍Kruskal算法的基本思想和证明,实现留在以后讨论. Kruskal算法的过程: (1) 将全部边按照权值由小到大排序. (2) 按顺序(边权由小到大的顺序)考虑每条边,只要这条边和我们已经选择的边不构成圈,就保留这条边,否则放弃这条边. 算法 成功选择(n-1)条边后,形成一个棵最小生成树,当然如果算法无法选择出(n-1)条边,则说明原图不连通. 以下图为例: 边排

hdu 1863 畅通工程 (并查集+最小生成树)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1863 畅通工程 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 17593    Accepted Submission(s): 7417 Problem Description 省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交

hdu 1272 小希的迷宫(并查集 最小生成树)

http://acm.hdu.edu.cn/showproblem.php?pid=1272 这题要求任意两个房间都相通又不能有环 即通过并查集求出是否构成最小生成树 #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define maxn 100000 int fa[maxn+10]; int num[maxn+10

CodeForces - 891C: Envy(可撤销的并查集&amp;最小生成树)

For a connected undirected weighted graph G, MST (minimum spanning tree) is a subgraph of G that contains all of G's vertices, is a tree, and sum of its edges is minimum possible. You are given a graph G. If you run a MST algorithm on graph it would

1863 畅通工程-并查集最小生成树

题目链接 问题描述: 简单的最小生成树的题,将路径按cost从小到大排序,利用克鲁斯塔尔求最小生成树算法就行. 代码: 1 #include<iostream> 2 #include<queue> 3 #include<algorithm> 4 5 using namespace std; 6 struct Road 7 { 8 int beg; 9 int end; 10 int cost; 11 Road(int beg, int end, int cost) 12

ACM : Travel-并查集-最小生成树 + 离线-解题报告

Travel Time Limit:1000MS     Memory Limit:131072KB     64bit IO Format:%I64d & %I64u /*题意 给出n[节点数],m[连线数],q[查询次数]; 输入m组数据 u[起点],v[终点],cost[权值]; (u,v)和 (v,u)表示两种不同的连线 输入q组查询数据: 要求 输出在m组数据中所有cost<q的所有节点连线的连线方式个数. 注意:每个拥有n个节点的联通块有 n*(n-1)个联通分量 (连线数):

hdu1863 畅通工程 并查集+最小生成树

Problem Description 省政府"畅通工程"的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可).经过调查评估,得到的统计表中列出了有可能建设公路的若干条道路的成本.现请你编写程序,计算出全省畅通需要的最低成本. Input 测试输入包含若干测试用例.每个测试用例的第1行给出评估的道路条数 N.村庄数目M ( < 100 ):随后的 N 行对应村庄间道路的成本,每行给出一对正整数,分别是两个村庄的编号,以及此两村庄间

hdu 1879 继续畅通工程 (并查集+最小生成树)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1879 继续畅通工程 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 14075    Accepted Submission(s): 6136 Problem Description 省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公